/* ==========================================================================
   PocketCorp Coder — components
   Monochrome, sharp, structural. Status is encoded with line-work, not color:
   idea = dotted · draft = dashed · scheduled = solid · published = filled.
   ========================================================================== */

/* ---------- Reset ---------- */

*, ::before, ::after {
  box-sizing: border-box;
  border-width: 0;
  border-style: solid;
  border-color: currentColor;
}

[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--pc-font-body);
  font-size: 0.8125rem;
  background: var(--pc-surface);
  color: var(--pc-ink);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 {
  font-family: var(--pc-font-display);
  text-transform: uppercase;
  letter-spacing: var(--pc-track-tight);
  font-weight: 500;
  margin: 0;
}

p { margin: 0; }
img, svg { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: none; padding: 0; cursor: pointer; }
input, textarea, select { font: inherit; color: inherit; }
a { color: inherit; }
ul, ol { margin: 0; padding: 0; list-style: none; }

:focus-visible {
  outline: 1.5px solid var(--pc-ink);
  outline-offset: 2px;
}

::selection { background: var(--pc-ink); color: var(--pc-surface); }

/* ---------- App frame ---------- */

.app {
  display: flex;
  min-height: 100vh;
  max-width: var(--pc-content-max);
  margin: 0 auto;
  /* `width: 100%` and `min-width: 0` together stop this box from ever being
     sized by its contents.
     The subtle one is width: on the Build/Data/Preview routes <body> becomes a
     flex column, and an auto cross-axis margin (the `margin: 0 auto` above)
     switches a flex item from stretch to fit-content. Without an explicit
     width, one long agent string would size .app to its max-content and push
     the whole page sideways — which is exactly what happened. */
  width: 100%;
  min-width: 0;
  border-left: 1px solid var(--pc-border-muted);
  border-right: 1px solid var(--pc-border-muted);
}

/* ---------- Splash / intro (brand stack-glitch, lifts like a curtain) ---------- */

.splash {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--pc-surface);
  color: var(--pc-ink);
  transition: transform 0.85s var(--pc-ease);
}

.splash.is-done { transform: translateY(-100%); pointer-events: none; }
.splash-hidden { display: none !important; }

.splash-inner { display: flex; flex-direction: column; align-items: center; gap: 16px; padding: 20px; }

.splash-title {
  font-family: var(--pc-font-display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--pc-track);
  font-size: clamp(1.9rem, 8vw, 3.6rem);
  line-height: 1;
}

.splash-sub {
  font-family: var(--pc-font-display);
  font-size: clamp(0.6rem, 2vw, 0.8rem);
  font-weight: 500;
  letter-spacing: var(--pc-track-logo);
  text-transform: uppercase;
  opacity: 0;
  animation: splash-sub-in 0.55s var(--pc-ease) 0.5s forwards;
}

@keyframes splash-sub-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: var(--pc-dim-2); transform: none; }
}

/* Thin loading bar under the wordmark, like the brand site's preloader:
   a hairline track whose fill sweeps in from the left and quickly fills. */
.splash-bar {
  width: 140px;
  height: 2px;
  margin-top: 12px;
  background: var(--pc-border);
  overflow: hidden;
  opacity: 0;
  animation: splash-fade-in 0.4s ease 0.4s forwards;
}

.splash-bar-fill {
  display: block;
  height: 100%;
  background: var(--pc-ink);
  transform: translateX(-101%);
  animation: splash-bar-fill 1.1s cubic-bezier(0.65, 0, 0.35, 1) 0.5s forwards;
}

@keyframes splash-fade-in { to { opacity: 1; } }
@keyframes splash-bar-fill { to { transform: translateX(0); } }

/* ---------- View / route transitions (fade out → skeleton → fade in) ---------- */

@keyframes view-enter {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

.view-enter { animation: view-enter 0.42s var(--pc-ease) both; }

@keyframes view-exit {
  from { opacity: 1; }
  to { opacity: 0; transform: translateY(-6px); }
}

.view-exit { animation: view-exit 0.15s ease both; }

/* ---------- Skeleton loaders (placeholders while data is fetched) ---------- */

.skeleton {
  position: relative;
  overflow: hidden;
  background: var(--pc-bg-hover);
}

.skeleton::after {
  content: '';
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, var(--pc-bg-hover), transparent);
  animation: skeleton-shimmer 1.2s ease-in-out infinite;
}

@keyframes skeleton-shimmer { to { transform: translateX(100%); } }

/* Skeletons live inside the real components (same classes, same geometry) so
   the loaded data fills in without any layout shift. */

/* Entrance animation for skeleton sections — staggered fade-up. The real
   content that replaces them does NOT re-run the layout animation; instead the
   text/data inside fades in via .content-in (boxes stay, content eases in). */
.sk-reveal { animation: view-enter 0.5s var(--pc-ease) both; }
.sk-reveal-d1 { animation-delay: 0.08s; }
.sk-reveal-d2 { animation-delay: 0.16s; }

@keyframes content-fade { from { opacity: 0; } to { opacity: 1; } }
.content-in { animation: content-fade 0.4s ease both; }

/* ---------- Sidebar ---------- */

.sidebar {
  width: var(--pc-sidebar-w);
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--pc-border-muted);
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.sidebar-logo {
  display: block;
  padding: 28px 24px 24px;
  font-family: var(--pc-font-display);
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: var(--pc-track-logo);
  text-transform: uppercase;
  text-decoration: none;
  border-bottom: 1px solid var(--pc-border-muted);
}

.sidebar-logo small {
  display: block;
  margin-top: 6px;
  font-family: var(--pc-font-body);
  font-size: 0.6rem;
  font-weight: 400;
  letter-spacing: 0.3em;
  opacity: var(--pc-dim-2);
}

.sidebar-nav { padding: 20px 0; display: flex; flex-direction: column; }

.side-label {
  padding: 14px 24px 8px;
  font-family: var(--pc-font-display);
  font-size: 0.55rem;
  font-weight: 500;
  letter-spacing: var(--pc-track-logo);
  text-transform: uppercase;
  opacity: var(--pc-dim-3);
}

.side-link {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 24px;
  font-family: var(--pc-font-display);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: var(--pc-track);
  text-transform: uppercase;
  text-decoration: none;
  opacity: var(--pc-dim-1);
  border-left: var(--pc-border-w) solid transparent;
  transition: opacity 0.25s ease, background 0.25s ease, border-left-color 0.25s ease;
}

.side-link:hover { opacity: 1; background: var(--pc-bg-hover); }

.side-link.is-active {
  opacity: 1;
  border-left-color: var(--pc-ink);
  background: var(--pc-bg-subtle);
}

.side-link .glyph { flex-shrink: 0; }

.side-divider {
  height: 1px;
  margin: 16px 24px;
  background: var(--pc-border-muted);
}

/* Two-letter platform tile, brutalist stand-in for brand logos */
.glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border: 1px solid var(--pc-border-strong);
  font-family: var(--pc-font-display);
  font-size: 0.5rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-indent: 0.08em;
}

.side-link.is-active .glyph,
.platform-card:hover .glyph {
  background: var(--pc-ink);
  color: var(--pc-surface);
  border-color: var(--pc-ink);
}

/* Brand-logo tiles: full-color logos sit on a white chip so they read on any
   surface in both light and dark themes (black marks like X / Threads included).
   Unlike the letter tiles, they keep their colors and don't invert. */
.glyph--brand {
  background: #fff;
  border: none;
}

.brand-svg {
  width: 72%;
  height: 72%;
}

/* Keep brand chips white and border-less in every "active" state. The doubled
   .glyph.glyph--brand raises specificity above the invert rules (some of which —
   e.g. the preset picker's — appear later in this file), so order doesn't matter. */
.side-link.is-active .glyph.glyph--brand,
.platform-card:hover .glyph.glyph--brand,
.preset.is-selected .glyph.glyph--brand {
  background: #fff;
  color: inherit;
  border: none;
}

.side-add {
  margin: 14px 24px;
  padding: 10px 0;
  font-family: var(--pc-font-display);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: var(--pc-track-wide);
  text-transform: uppercase;
  border: var(--pc-border-w) dashed var(--pc-border-strong);
  text-align: center;
  transition: all 0.3s ease-out;
}

.side-add:hover { background: var(--pc-ink); color: var(--pc-surface); border-style: solid; border-color: var(--pc-ink); }

.sidebar-foot {
  margin-top: auto;
  padding: 16px 24px;
  border-top: 1px solid var(--pc-border-muted);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.sidebar-foot .hint {
  font-size: 0.58rem;
  letter-spacing: 0.06em;
  opacity: var(--pc-dim-3);
}

/* ---------- Theme toggle (sun/moon morph from the brand site) ---------- */

.theme-toggle { padding: 6px; display: flex; border-radius: 0; }

.theme-toggle svg { overflow: visible; transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1); }
.dark .theme-toggle svg { transform: rotate(270deg); }

.tt-mask-circle { transition: cx 0.6s cubic-bezier(0.34,1.56,0.64,1), cy 0.6s cubic-bezier(0.34,1.56,0.64,1); cx: 33; cy: 0; }
.dark .tt-mask-circle { cx: 17; cy: 8; }

.tt-circle { transition: r 0.6s cubic-bezier(0.34,1.56,0.64,1); r: 5; }
.dark .tt-circle { r: 9; }

.tt-rays {
  transform-origin: 50% 50%;
  transform-box: fill-box;
  transition: opacity 0.6s cubic-bezier(0.34,1.56,0.64,1), transform 0.6s cubic-bezier(0.34,1.56,0.64,1);
}
.dark .tt-rays { opacity: 0; transform: scale(0) rotate(-30deg); }

/* ---------- Content area ---------- */

.content {
  flex: 1;
  min-width: 0;
  padding: 44px 56px 80px;
}

.page-head { margin-bottom: 36px; }

.eyebrow {
  font-family: var(--pc-font-display);
  font-size: 0.58rem;
  font-weight: 500;
  letter-spacing: var(--pc-track-logo);
  text-transform: uppercase;
  opacity: var(--pc-dim-2);
  margin-bottom: 10px;
}

.page-title {
  font-size: clamp(1.4rem, 3vw, 2rem);
  letter-spacing: var(--pc-track);
}

.page-sub {
  margin-top: 12px;
  font-size: 0.72rem;
  line-height: 1.9;
  max-width: 520px;
  opacity: var(--pc-dim-2);
}

.page-head-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
}

/* ---------- Stack glitch (signature, ported from pocketcorp.agency) ---------- */

.stack-glitch { position: relative; display: inline-grid; grid-template-columns: 1fr; }

.stack-glitch__slice {
  grid-row-start: 1;
  grid-column-start: 1;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: inherit;
  white-space: nowrap;
  --stack-height: calc(100% / var(--stacks) - 1px);
  --inverse-index: calc(calc(var(--stacks) - 1) - var(--index));
  --clip-top: calc(var(--stack-height) * var(--index));
  --clip-bottom: calc(var(--stack-height) * var(--inverse-index));
  clip-path: inset(var(--clip-top) 0 var(--clip-bottom) 0);
  animation: stack-glitch-stack 340ms cubic-bezier(0.46, 0.29, 0, 1.24) 1 backwards calc(var(--index) * 120ms);
}

@keyframes stack-glitch-stack {
  0% { opacity: 0; transform: translateX(-50%); text-shadow: -2px 3px 0 red, 2px -3px 0 blue; }
  60% { opacity: 0.5; transform: translateX(50%); }
  80% { transform: none; opacity: 1; text-shadow: 2px -3px 0 red, -2px 3px 0 blue; }
  100% { text-shadow: none; }
}

@media (prefers-reduced-motion: reduce) {
  .stack-glitch__slice { animation: none; }
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--pc-font-display);
  font-size: 0.65rem;
  font-weight: 500;
  letter-spacing: var(--pc-track-wide);
  text-transform: uppercase;
  padding: 12px 32px;
  border: var(--pc-border-w) solid currentColor;
  background: transparent;
  color: inherit;
  cursor: pointer;
  transition: all 0.3s ease-out;
  text-decoration: none;
  border-radius: var(--pc-radius);
}

.btn:hover:not(:disabled) { background: var(--pc-ink); color: var(--pc-surface); border-color: var(--pc-ink); }
.btn:disabled { opacity: 0.4; cursor: not-allowed; }

.btn--fill { background: var(--pc-ink); color: var(--pc-surface); border-color: var(--pc-ink); }
.btn--fill:hover:not(:disabled) { background: transparent; color: var(--pc-ink); }

.btn--sm { padding: 8px 18px; font-size: 0.58rem; }

.btn--ghost { border-color: transparent; opacity: var(--pc-dim-1); }
.btn--ghost:hover:not(:disabled) { opacity: 1; background: var(--pc-bg-hover); color: inherit; border-color: transparent; }

.btn--danger:hover:not(:disabled) { background: var(--pc-danger); border-color: var(--pc-danger); color: #fff; }

/* ---------- Cards & tiles ---------- */

.grid { display: grid; gap: var(--pc-gap); }
.grid--stats { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }
.grid--cards { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }

.card {
  border: 1px solid var(--pc-border);
  background: var(--pc-bg-subtle);
  padding: 24px;
  border-radius: var(--pc-radius);
}

.stat-tile {
  border: 1px solid var(--pc-border);
  padding: 20px 24px;
  transition: transform 0.3s var(--pc-ease), border-color 0.3s ease;
}

.stat-tile:hover { transform: translateY(-3px); border-color: var(--pc-border-hover); }

.stat-tile .num {
  font-family: var(--pc-font-display);
  font-size: 2rem;
  font-weight: 500;
  line-height: 1.1;
}

.stat-tile .lbl {
  margin-top: 6px;
  font-family: var(--pc-font-display);
  font-size: 0.55rem;
  font-weight: 500;
  letter-spacing: var(--pc-track-logo);
  text-transform: uppercase;
  opacity: var(--pc-dim-2);
}

.platform-card {
  display: block;
  text-decoration: none;
  border: 1px solid var(--pc-border);
  padding: 24px;
  transition: border-color 0.3s ease, background 0.3s ease, transform 0.3s var(--pc-ease);
}

.platform-card:hover { border-color: var(--pc-border-hover); background: var(--pc-bg-subtle); transform: translateY(-3px); }

.platform-card .glyph { width: 34px; height: 34px; font-size: 0.62rem; margin-bottom: 16px; transition: all 0.3s ease; }

.platform-card h3 { font-size: 0.8rem; letter-spacing: var(--pc-track); }

.platform-card .meta {
  margin-top: 8px;
  font-size: 0.62rem;
  letter-spacing: 0.04em;
  opacity: var(--pc-dim-2);
}

.section { margin-top: 48px; }

.section-title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 12px;
  margin-bottom: 20px;
  border-bottom: 1px solid var(--pc-border);
}

.section-title h2 { font-size: 0.78rem; letter-spacing: var(--pc-track); }
.section-title .count { font-size: 0.62rem; opacity: var(--pc-dim-3); letter-spacing: 0.1em; }

/* ---------- Forms ---------- */

.field { display: flex; flex-direction: column; gap: 8px; }

.field label {
  font-family: var(--pc-font-display);
  font-size: 0.58rem;
  font-weight: 500;
  letter-spacing: var(--pc-track);
  text-transform: uppercase;
}

.field label .opt { opacity: var(--pc-dim-3); letter-spacing: 0.08em; }

.field .help { font-size: 0.6rem; line-height: 1.7; opacity: var(--pc-dim-3); }

.input, .textarea, .select {
  font-family: var(--pc-font-body);
  font-size: 0.75rem;
  padding: 11px 14px;
  border: var(--pc-border-w) solid var(--pc-border);
  background: transparent;
  color: var(--pc-ink);
  outline: none;
  transition: border-color 0.3s;
  border-radius: var(--pc-radius);
  width: 100%;
}

.input:focus, .textarea:focus, .select:focus { border-color: var(--pc-border-hover); }
.input::placeholder, .textarea::placeholder { color: inherit; opacity: 0.35; }

.textarea { resize: vertical; min-height: 96px; line-height: 1.8; }

.select {
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5'%3E%3Cpath d='M0 0l4 5 4-5z' fill='%23808080'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 34px;
}

.dark .select option { background: var(--pc-surface); }

.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.form-stack { display: flex; flex-direction: column; gap: 18px; }

.form-error { font-size: 0.68rem; color: var(--pc-danger); }

/* ---------- Tabs ---------- */

.tabs {
  display: flex;
  gap: 28px;
  border-bottom: 1px solid var(--pc-border);
  margin: 32px 0 28px;
  /* Scroll horizontally instead of overflowing when the tabs don't fit
     (e.g. all platform tabs on a narrow phone). Scrollbar hidden. */
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}

.tabs::-webkit-scrollbar { display: none; }

.tab {
  flex-shrink: 0;
  white-space: nowrap;
  font-family: var(--pc-font-display);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: var(--pc-track);
  text-transform: uppercase;
  padding: 0 2px 12px;
  opacity: var(--pc-dim-2);
  border-bottom: var(--pc-border-w) solid transparent;
  margin-bottom: -1px;
  transition: opacity 0.25s ease;
}

.tab:hover { opacity: 1; }
.tab.is-active { opacity: 1; border-bottom-color: var(--pc-ink); }

/* ---------- Markdown view / editor (Raw ⇄ Preview) ---------- */

/* Control row: view toggle on the left, fullscreen button on the right.
   Sticky so it stays visible while the content scrolls (e.g. feed articles). */
.md-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
  position: sticky;
  top: 0;
  z-index: 3;
  background: var(--pc-surface);
  padding-bottom: 6px;
}

.md-actions { display: flex; align-items: center; gap: 6px; }

.md-fs-btn,
.md-icon-btn {
  width: 26px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.8rem;
  border: 1px solid var(--pc-border-strong);
  flex-shrink: 0;
  color: var(--pc-ink);
  transition: all 0.2s ease;
}

.md-icon-btn svg { display: block; }

.md-fs-btn:hover,
.md-icon-btn:hover { background: var(--pc-ink); color: var(--pc-surface); border-color: var(--pc-ink); }

.md-copy-btn.copied { background: var(--pc-ink); color: var(--pc-surface); border-color: var(--pc-ink); }

.md-toggle {
  display: inline-flex;
  border: 1px solid var(--pc-border-strong);
  align-self: flex-start;
}

/* Fullscreen: the component fills the viewport above the modal. */
.md-view.is-fullscreen,
.md-editor.is-fullscreen {
  position: fixed;
  inset: 0;
  z-index: 600;
  margin: 0;
  padding: 16px 22px 22px;
  background: var(--pc-surface);
  overflow-y: auto;
}

.md-editor.is-fullscreen .textarea,
.md-editor.is-fullscreen .md-editor-preview {
  min-height: calc(100vh - 90px);
  max-height: none;
}

body.has-fullscreen { overflow: hidden; }

.md-toggle-btn {
  font-family: var(--pc-font-display);
  font-size: 0.52rem;
  font-weight: 500;
  letter-spacing: var(--pc-track);
  text-transform: uppercase;
  padding: 5px 12px;
  transition: background 0.2s ease, color 0.2s ease;
}

.md-toggle-btn + .md-toggle-btn { border-left: 1px solid var(--pc-border-strong); }
.md-toggle-btn.is-active { background: var(--pc-ink); color: var(--pc-surface); }

.md-view, .md-editor { display: flex; flex-direction: column; }

.md-raw {
  font-family: var(--pc-font-body);
  font-size: 0.7rem;
  line-height: 1.7;
  white-space: pre-wrap;
  word-break: break-word;
  margin: 0;
}

/* Rendered markdown typography (kept restrained, on-brand). */
.markdown { font-size: 0.74rem; line-height: 1.85; word-break: break-word; }
.markdown > *:first-child { margin-top: 0; }
.markdown > *:last-child { margin-bottom: 0; }
.markdown p { margin: 0 0 12px; }
.markdown h1, .markdown h2, .markdown h3, .markdown h4 {
  font-family: var(--pc-font-display);
  letter-spacing: var(--pc-track-tight);
  margin: 18px 0 10px;
  line-height: 1.3;
}
.markdown h1 { font-size: 0.98rem; }
.markdown h2 { font-size: 0.86rem; }
.markdown h3 { font-size: 0.76rem; }
.markdown h4 { font-size: 0.7rem; }
.markdown ul, .markdown ol { margin: 0 0 12px; padding-left: 20px; }
.markdown ul { list-style: disc; }
.markdown ol { list-style: decimal; }
.markdown li { margin-bottom: 4px; }
.markdown a { text-decoration: underline; text-underline-offset: 2px; }
.markdown code {
  font-family: var(--pc-font-body);
  font-size: 0.92em;
  padding: 1px 5px;
  border: 1px solid var(--pc-border);
  background: var(--pc-bg-subtle);
}
.markdown pre {
  border: 1px solid var(--pc-border);
  background: var(--pc-bg-subtle);
  padding: 12px 14px;
  overflow-x: auto;
  margin: 0 0 12px;
}
.markdown pre code { border: none; padding: 0; background: none; }
.markdown blockquote {
  margin: 0 0 12px;
  padding-left: 12px;
  border-left: 2px solid var(--pc-border-strong);
  opacity: var(--pc-dim-1);
}
.markdown img { max-width: 100%; height: auto; }
.markdown hr { border: none; border-top: 1px solid var(--pc-border); margin: 16px 0; }
.markdown table { border-collapse: collapse; font-size: 0.68rem; margin: 0 0 12px; }
.markdown th, .markdown td { border: 1px solid var(--pc-border); padding: 5px 8px; text-align: left; }

.md-editor-preview {
  min-height: 96px;
  border: var(--pc-border-w) solid var(--pc-border);
  padding: 11px 14px;
  max-height: 320px;
  overflow-y: auto;
}

/* ---------- Code editor (URL reader) with syntax highlighting ---------- */

/* Shared metrics — the textarea and the highlight layer MUST match exactly. */
.code-editor,
.code-hl {
  font-family: var(--pc-font-body);
  font-size: 0.68rem;
  line-height: 1.6;
  white-space: pre;
  overflow-wrap: normal;
  tab-size: 4;
  padding: 11px 14px;
  border: var(--pc-border-w) solid transparent;
  margin: 0;
}

.code-wrap { position: relative; }

/* Highlight layer sits behind the (transparent) textarea. */
.code-hl {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  color: var(--pc-ink);
  background: transparent;
  border-radius: var(--pc-radius);
}

.code-hl code { font: inherit; white-space: inherit; }

.code-wrap .code-editor {
  position: relative;
  z-index: 1;
  overflow: auto;
  color: transparent;
  -webkit-text-fill-color: transparent;   /* Safari: hide textarea glyphs */
  caret-color: var(--pc-ink);
  background: transparent;
  border-color: var(--pc-border);
}

.code-wrap .code-editor:focus { border-color: var(--pc-border-hover); }

/* highlight.js tokens mapped to the muted brand palette (see theme.css). */
.code-hl .hljs-comment,
.code-hl .hljs-quote { color: var(--pc-tok-comment); font-style: italic; }
.code-hl .hljs-string,
.code-hl .hljs-meta .hljs-string,
.code-hl .hljs-regexp { color: var(--pc-tok-string); }
.code-hl .hljs-keyword,
.code-hl .hljs-literal,
.code-hl .hljs-type,
.code-hl .hljs-name { color: var(--pc-tok-keyword); font-weight: 500; }
.code-hl .hljs-number { color: var(--pc-tok-number); }
.code-hl .hljs-built_in,
.code-hl .hljs-title,
.code-hl .hljs-title.function_,
.code-hl .hljs-title.class_,
.code-hl .hljs-attr,
.code-hl .hljs-params { color: var(--pc-tok-builtin); }
.code-hl .hljs-decorator,
.code-hl .hljs-meta { color: var(--pc-tok-builtin); }

/* ---------- Modal & wizard ---------- */

.overlay {
  position: fixed;
  inset: 0;
  z-index: 400;   /* above the mobile topbar (290) so modals aren't clipped */
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  padding: 20px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
}

.overlay.is-open { opacity: 1; pointer-events: auto; }

.modal {
  --m-pad-x: 40px;
  --m-pad-y: 36px;
  width: 100%;
  max-width: 560px;   /* Material: dialogs cap at 560dp wide */
  /* Material: keep a >=48px margin from the top/bottom edges — shrink and
     scroll internally rather than filling the screen. dvh (with a vh fallback)
     measures the *visible* viewport so mobile browser toolbars don't push the
     modal to full height. */
  max-height: min(600px, calc(100vh - 96px));
  max-height: min(600px, calc(100dvh - 96px));
  overflow-y: auto;
  background: var(--pc-surface);
  border: var(--pc-border-w) solid var(--pc-border-strong);
  color: var(--pc-ink);
  padding: var(--m-pad-y) var(--m-pad-x) 40px;
}

/* Open animation: first stretch out to a line along the X axis, then unfold
   the height to top and bottom, then fade the content in. `.modal-anim` is
   added by Modal.open only on a fresh open (not on wizard step re-renders)
   and removed on animationend. */
.modal-anim {
  animation: modal-unfold 0.62s var(--pc-ease) both;
  transform-origin: center;
}

@keyframes modal-unfold {
  0% { transform: scale(0, 0.004); }
  45% { transform: scale(1, 0.004); }
  100% { transform: scale(1, 1); }
}

.modal-anim > * { animation: modal-content-in 0.3s ease 0.52s both; }

@keyframes modal-content-in { from { opacity: 0; } to { opacity: 1; } }

.modal--wide { max-width: 680px; }

/* Title + close button stay pinned while the modal body scrolls. Negative
   margins bleed the header over the modal padding so scrolled content can't
   peek through at the edges. */
.modal-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  position: sticky;
  top: calc(-1 * var(--m-pad-y));
  z-index: 5;
  background: var(--pc-surface);
  margin: calc(-1 * var(--m-pad-y)) calc(-1 * var(--m-pad-x)) 8px;
  padding: var(--m-pad-y) var(--m-pad-x) 12px;
}

.modal-title { font-size: 0.9rem; letter-spacing: var(--pc-track); }

.modal-close { opacity: var(--pc-dim-2); padding: 4px; line-height: 1; font-size: 1rem; transition: opacity 0.2s; }
.modal-close:hover { opacity: 1; }

.modal-sub { font-size: 0.66rem; line-height: 1.8; opacity: var(--pc-dim-2); margin-bottom: 24px; max-width: 420px; }

.modal-actions { display: flex; justify-content: space-between; gap: 12px; margin-top: 28px; }
.modal-actions .spacer { flex: 1; }

/* Wizard step rail */
.steps { display: flex; gap: 8px; margin: 0 0 28px; }

.step-dot {
  flex: 1;
  display: flex;
  flex-direction: column;
}

/* The progress bar sits below its label. */
.step-dot::after {
  content: '';
  display: block;
  height: 2px;
  background: var(--pc-border);
  transition: background 0.3s ease;
}

.step-dot.is-done::after, .step-dot.is-current::after { background: var(--pc-ink); }

.step-label {
  font-family: var(--pc-font-display);
  font-size: 0.52rem;
  font-weight: 500;
  letter-spacing: var(--pc-track);
  text-transform: uppercase;
  opacity: var(--pc-dim-3);
  margin-bottom: 6px;
  display: block;
}

.step-dot.is-current .step-label, .step-dot.is-done .step-label { opacity: 1; }

/* Platform preset picker */
.preset-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }

.preset {
  border: 1px solid var(--pc-border);
  padding: 16px 10px 14px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  transition: all 0.25s ease;
}

.preset .glyph { width: 30px; height: 30px; font-size: 0.58rem; }

.preset span {
  font-family: var(--pc-font-display);
  font-size: 0.55rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.preset:hover { border-color: var(--pc-border-hover); background: var(--pc-bg-subtle); }

.preset.is-selected { border: var(--pc-border-w) solid var(--pc-ink); background: var(--pc-bg-subtle); }
.preset.is-selected .glyph { background: var(--pc-ink); color: var(--pc-surface); border-color: var(--pc-ink); }

/* ---------- Empty states ---------- */

.empty {
  border: var(--pc-border-w) dashed var(--pc-border);
  padding: 56px 32px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.empty h3 { font-size: 0.78rem; letter-spacing: var(--pc-track); }
.empty p { font-size: 0.66rem; line-height: 1.9; opacity: var(--pc-dim-2); max-width: 340px; }

/* ---------- Toast ---------- */

.toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translate(-50%, 80px);
  z-index: 500;   /* above the modal overlay (400) */
  background: var(--pc-surface-inverse);
  color: var(--pc-ink-inverse);
  font-family: var(--pc-font-display);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: var(--pc-track);
  text-transform: uppercase;
  padding: 12px 24px;
  transition: transform 0.35s var(--pc-ease);
  pointer-events: none;
}

.toast.is-visible { transform: translate(-50%, 0); }
.toast.is-error { background: var(--pc-danger); color: #fff; }

/* ---------- Reveal ---------- */

.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.7s var(--pc-ease), transform 0.7s var(--pc-ease);
}

.reveal.is-visible { opacity: 1; transform: translateY(0); }

.reveal-d1 { transition-delay: 0.06s; }
.reveal-d2 { transition-delay: 0.12s; }
.reveal-d3 { transition-delay: 0.18s; }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  .overlay, .modal, .toast { transition: none; }
  .view-enter, .view-exit, .sk-reveal, .content-in { animation: none; }
  .splash { transition: none; }
  .splash-sub { animation: none; opacity: var(--pc-dim-2); }
  .splash-bar, .splash-bar-fill { animation: none; opacity: 1; transform: none; }
  .platform-card:hover, .stat-tile:hover { transform: none; }
  .modal-anim { animation: none; }
  .modal-anim > * { animation: none; }
  .skeleton::after { animation: none; }
}

/* ---------- Utility ---------- */

.muted { opacity: var(--pc-dim-2); }
.mt-8 { margin-top: 8px; }
.mt-16 { margin-top: 16px; }
.mt-24 { margin-top: 24px; }
.mono-sm { font-size: 0.62rem; letter-spacing: 0.04em; }

/* ---------- Mobile topbar + burger (hidden on desktop) ---------- */

.topbar { display: none; }
.nav-scrim { display: none; }

.topbar-logo {
  font-family: var(--pc-font-display);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: var(--pc-track-logo);
  text-transform: uppercase;
  text-decoration: none;
  line-height: 1;
}

.topbar-logo small {
  font-family: inherit;
  font-weight: 400;
  font-size: inherit;
  letter-spacing: var(--pc-track-logo);
  opacity: var(--pc-dim-2);
  margin-left: 0.5em;
}

/* On mobile the theme toggle is moved here from the sidebar footer. */
.topbar .theme-toggle { margin-left: auto; }

.burger {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 28px;
  height: 40px;
  padding: 9px 3px;
  flex-shrink: 0;
}

.burger span {
  display: block;
  height: 1.5px;
  width: 100%;
  background: var(--pc-ink);
  transition: transform 0.3s var(--pc-ease), opacity 0.2s ease;
}

/* Burger morphs into an X while the drawer is open. */
body.nav-open .burger span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
body.nav-open .burger span:nth-child(2) { opacity: 0; }
body.nav-open .burger span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* ---------- Responsive ---------- */

@media (max-width: 860px) {
  .app { border: none; }

  /* Fixed top bar with the burger; carries the wordmark on small screens. */
  .topbar {
    display: flex;
    align-items: center;
    gap: 16px;
    position: sticky;
    top: 0;
    z-index: 290;
    padding: 12px 20px;
    background: var(--pc-surface);
    border-bottom: 1px solid var(--pc-border-muted);
  }

  /* Sidebar becomes an off-canvas drawer sliding in from the left. */
  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    width: min(310px, 84vw);
    height: 100vh;
    z-index: 280;
    background: var(--pc-surface);
    border-right: 1px solid var(--pc-border-muted);
    transform: translateX(-100%);
    transition: transform 0.32s var(--pc-ease);
  }
  body.nav-open .sidebar { transform: translateX(0); }

  .nav-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 270;
    background: rgba(0, 0, 0, 0.55);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
  }

  .content { padding: 28px 20px 64px; }
  .tabs { gap: 18px; margin: 24px 0 22px; }
  .tab { padding: 0 2px 14px; }   /* a touch more height to tap comfortably */
  .form-row { grid-template-columns: 1fr; }
  .preset-grid { grid-template-columns: repeat(2, 1fr); }
  .modal { --m-pad-x: 22px; --m-pad-y: 28px; padding: var(--m-pad-y) var(--m-pad-x) 32px; }

  /* Less headroom per page — on a phone the title has already done its job
     by the second line, and the space is worth more as content. */
  .page-head { margin-bottom: 22px; }

  /* iOS (and some Android WebViews) zoom the whole page on focusing any text
     input under 16px — the classic "tap a field, page jumps" bug. Every
     plain form control clears the threshold here; component-specific inputs
     with their own class (composer, colour fields, the SQL grid) get the
     same treatment in coder.css, which loads after this and wins ties by
     source order, but needs an equal-or-higher-specificity selector to beat
     rules more specific than a bare `.input`. */
  .input, .textarea, .select { font-size: 16px; }

  /* Two columns instead of one giant tile per row — auto-fit's 170px minimum
     can't fit two on a phone, so without this every stat is a full screen's
     width of mostly empty space. The value shrinks to match; 2rem was sized
     for a tile with room to spare, not a half-width phone column. */
  .grid--stats { grid-template-columns: repeat(2, 1fr); gap: 12px; }
  .stat-tile { padding: 14px 16px; }
  .stat-tile .num { font-size: 1.5rem; }

  /* A few extra pixels of vertical padding on the smallest tap targets —
     visually near-identical, comfortably easier to hit with a thumb. */
  .btn--sm { padding: 10px 16px; }
  .theme-chip { padding: 8px 12px 8px 7px; }
  .base-chip { padding: 9px 12px; }
  .seed { padding: 9px 13px; }
}

@media (prefers-reduced-motion: reduce) {
  .sidebar, .burger span { transition: none; }
}
