@font-face {
  font-family: "InterVariable";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/assets/fonts/InterVariable.woff2") format("woff2");
}
@font-face {
  font-family: "InterVariable";
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url("/assets/fonts/InterVariable-Italic.woff2") format("woff2");
}

/**
 * The fallback is measured to Inter rather than merely named after it.
 * Without these overrides the swap from the system face to Inter shifts every
 * line on the page — the metric mismatch is what "the fonts pop" looks like.
 */
@font-face {
  font-family: "Inter Fallback";
  src: local("Segoe UI"), local("Helvetica Neue"), local("Arial");
  ascent-override: 90%;
  descent-override: 22.43%;
  line-gap-override: 0%;
  size-adjust: 107.12%;
}

/* Issa Digital Estate — the house style.
 *
 * Editorial, not SaaS. A fashion house's own tools should look like the house:
 * true-neutral greys so nothing competes with product imagery, one accent —
 * the house's own blue, read off its own website templates — crisp geometry
 * than pillowy cards, and typography doing the work — tight tracking on
 * display sizes, wide-tracked uppercase for the small labels that fashion
 * has used on spec sheets and line lists forever.
 *
 * Tokens are OKLCH: perceptually uniform, so a dark theme is a redefinition
 * of the same names rather than a second palette to keep in sync. Neutrals
 * hold almost no chroma; only the accent carries any.
 */

:root {
  color-scheme: light dark;

  /* White. The house's own ground is white, the rules are hairlines, the
     text is black, and every colour in view belongs to a garment. Nothing in
     the chrome competes with product photography — which on a fashion site is
     the entire design brief. */
  --bg:        oklch(1 0 0);
  --surface:   oklch(1 0 0);
  --raised:    oklch(0.972 0.001 90);
  --fg:        oklch(0.16 0 0);
  --fg-muted:  oklch(0.48 0 0);
  --fg-faint:  oklch(0.66 0 0);
  --line:      oklch(0.885 0 0);
  --line-soft: oklch(0.932 0 0);

  /* Black is the interface colour: buttons, emphasis, the active state. The
     house blue appears only where something must read as live — a focus ring,
     a running tool, a series on a chart — and never as decoration.

     This is the Issa blue, read off the house's own website templates —
     the flat panel fill in the Product Detail prototype: #1C85BA,
     oklch(0.586 0.120 237). It clears 4.11:1 on white, which carries a UI
     component but sits just under the 4.5:1 that body text wants, so small
     text and links use --accent-ink: the same hue, one step darker. One blue
     in two steps; never a second blue. */
  --accent:      oklch(0.586 0.120 237);
  --accent-ink:  oklch(0.520 0.130 237);
  --accent-fg:   oklch(1 0 0);
  --accent-soft: oklch(0.586 0.120 237 / 0.12);
  --accent-line: oklch(0.586 0.120 237 / 0.40);

  /* Reserved. A status colour never doubles as "series 4" — if green can mean
     both "healthy" and "the third factory", it means neither. */
  --ok:      oklch(0.55 0.13 155);
  --warn:    oklch(0.65 0.14 75);
  --bad:     oklch(0.55 0.19 27);

  /* Chart series.
     Not chosen by eye: these six were run through a contrast and
     colour-vision check against this exact surface, and the ORDER is part of
     the result — the validator scores adjacent pairs, since adjacent is what
     a reader compares in a stacked bar, and this sequence is one that clears
     every pair in both light and dark. Reordering them silently breaks that,
     so add a seventh series by folding into "other", never by inventing a hue. */
  --chart-1: oklch(0.586 0.120 237);  /* the house blue, exactly as the templates use it */
  --chart-2: oklch(0.640 0.145 72);
  --chart-3: oklch(0.500 0.165 344);
  --chart-4: oklch(0.570 0.135 148);
  --chart-5: oklch(0.460 0.175 300);
  /* Five identities, then "other". A sixth hue would have to sit between two
     of the above and it failed every check that matters; a neutral bucket is
     honest where an invented colour is not. */
  --chart-6: oklch(0.62 0.006 250);

  /* A scrollbar is chrome, and this house's chrome is a hairline. The thumb
     is the same grey as a rule so a scrolling region reads as ruled rather
     than as a widget bolted on; it only darkens under the cursor. */
  --scroll-thumb:       oklch(0.855 0 0);
  --scroll-thumb-hover: oklch(0.68 0 0);

  --r-xs: 3px;
  --r-sm: 5px;
  --r-md: 8px;
  --r-lg: 12px;

  --sans: "InterVariable", "Inter Fallback", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Code", Menlo, monospace;

  --shadow-sm: 0 1px 2px oklch(0 0 0 / 0.05);
  --shadow-md: 0 4px 16px oklch(0 0 0 / 0.07), 0 1px 3px oklch(0 0 0 / 0.05);
}

:root[data-theme="dark"],
:root:not([data-theme="light"]) {
  @media (prefers-color-scheme: dark) {
    --bg:        oklch(0.135 0 0);
    --surface:   oklch(0.165 0 0);
    --raised:    oklch(0.205 0 0);
    --fg:        oklch(0.96 0 0);
    --fg-muted:  oklch(0.64 0 0);
    --fg-faint:  oklch(0.48 0 0);
    --line:      oklch(0.28 0 0);
    --line-soft: oklch(0.225 0 0);
    /* On a dark ground the true blue is already readable, so ink and fill
       are the same step. */
    --accent:      oklch(0.655 0.125 237);
    --accent-ink:  oklch(0.655 0.125 237);
    --accent-soft: oklch(0.655 0.125 237 / 0.18);
    --accent-line: oklch(0.655 0.125 237 / 0.45);
    --ok:      oklch(0.70 0.13 155);
    --warn:    oklch(0.76 0.13 75);
    --bad:     oklch(0.68 0.17 27);
    /* Stepped for the dark ground, not flipped: same hues, lighter steps,
       re-checked against this surface. */
    --chart-1: oklch(0.655 0.125 237);
    --chart-2: oklch(0.660 0.140 75);
    --chart-3: oklch(0.650 0.155 344);
    --chart-4: oklch(0.660 0.135 148);
    --chart-5: oklch(0.640 0.160 300);
    --chart-6: oklch(0.62 0.006 250);
    --shadow-sm: 0 1px 2px oklch(0 0 0 / 0.4);
    --shadow-md: 0 4px 20px oklch(0 0 0 / 0.45), 0 1px 3px oklch(0 0 0 / 0.3);
  }
}
:root[data-theme="dark"] {
  --bg:        oklch(0.135 0 0);
  --surface:   oklch(0.165 0 0);
  --raised:    oklch(0.205 0 0);
  --fg:        oklch(0.96 0 0);
  --fg-muted:  oklch(0.64 0 0);
  --fg-faint:  oklch(0.48 0 0);
  --line:      oklch(0.28 0 0);
  --line-soft: oklch(0.225 0 0);
  --accent:      oklch(0.655 0.125 237);
  --accent-ink:  oklch(0.655 0.125 237);
  --accent-soft: oklch(0.655 0.125 237 / 0.18);
  --accent-line: oklch(0.655 0.125 237 / 0.45);
  --ok:      oklch(0.70 0.13 155);
  --warn:    oklch(0.76 0.13 75);
  --bad:     oklch(0.68 0.17 27);
  --chart-1: oklch(0.655 0.125 237);
  --chart-2: oklch(0.660 0.140 75);
  --chart-3: oklch(0.650 0.155 344);
  --chart-4: oklch(0.660 0.135 148);
  --chart-5: oklch(0.640 0.160 300);
  --chart-6: oklch(0.62 0.006 250);
  --shadow-sm: 0 1px 2px oklch(0 0 0 / 0.4);
  --shadow-md: 0 4px 20px oklch(0 0 0 / 0.45), 0 1px 3px oklch(0 0 0 / 0.3);
}

*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 400 14px/1.55 var(--sans);
  letter-spacing: -0.011em;
  /* Contextual alternates on, and Inter's optical sizing follows the size —
     display cuts for headings, text cuts for body, from the one file. */
  font-feature-settings: "calt" 1;
  font-optical-sizing: auto;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Headlines set tight and balanced; body copy avoids a one-word last line.
   Both degrade to nothing where unsupported, so neither needs a guard. */
h1, h2, h3, .display { text-wrap: balance; }
p, .lede, .dept-about, .door-a { text-wrap: pretty; }

/* Numbers line up in tables, charts and anything money-shaped. */
table, .num, .metric, .chart text, .mono { font-variant-numeric: tabular-nums; }

a { color: inherit; text-decoration-color: var(--accent-line); text-underline-offset: 2px; }
a:hover { text-decoration-color: var(--accent); }

/* ── The fashion micro-label: wide-tracked uppercase, used for eyebrows ── */
.eyebrow {
  font-size: 10px;
  font-weight: 550;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-faint);
}

h1, h2, h3 { margin: 0; font-weight: 560; letter-spacing: -0.022em; }
h1 { font-size: 24px; line-height: 1.2; }

/* Display: a fashion house sets its own name large and light. Weight 350 at
   size, tracking pulled in — the opposite of a dashboard's bold 24px. */
.display {
  font-size: clamp(32px, 4.4vw, 52px);
  font-weight: 350;
  line-height: 1.04;
  letter-spacing: -0.035em;
  margin: 0;
}
.lede { font-size: 16px; line-height: 1.6; color: var(--fg-muted); max-width: 58ch; }

/* A band of figures separated by rules rather than boxed like a dashboard. */
.figures {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  border-top: 1px solid var(--line);
  /* The rule is drawn ON this element's top edge, so it needs clearance of
     its own — without it the element above rests against the line. */
  margin-top: 28px;
}
/* Each cell carries a rule on its right, which means every cell after the
   first has a line immediately to the LEFT of its content. With no left
   padding the number sat on that line. Padding goes on both sides; the outer
   edges give theirs back so the row still aligns to the page margin. */
.figures > div { padding: 18px 20px; border-right: 1px solid var(--line-soft); }
.figures > div:first-child { padding-left: 0; }
.figures > div:last-child { border-right: 0; padding-right: 0; }
.figures .fig { font-size: 30px; font-weight: 350; letter-spacing: -0.035em; line-height: 1; }
.figures .cap { margin-top: 7px; font-size: 11px; color: var(--fg-muted); }

/* Doors: a hairline above, no box. The rule is the structure. */
.doors { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 0; border-top: 1px solid var(--line); }
.door {
  display: block; text-decoration: none; color: inherit;
  padding: 22px 26px 26px 0; border-right: 1px solid var(--line-soft);
  transition: background 160ms ease-out;
}
.door:last-child { border-right: 0; }
.door:hover { background: var(--raised); }
.door .door-t { display: flex; align-items: center; gap: 9px; font-size: 16px; font-weight: 450; letter-spacing: -0.02em; }
.door .door-a { margin-top: 8px; color: var(--fg-muted); font-size: 13px; line-height: 1.5; max-width: 34ch; }
.door .door-w { margin-top: 16px; }
.door svg { color: var(--fg-faint); transition: color 160ms ease-out; }
.door:hover svg { color: var(--fg); }

/* The collection strip: the house's own clothes, because a fashion tool that
   shows no clothes is a spreadsheet with a logo on it. */
/* A caption is three rungs, because a garment here is three facts: the
   reference it is filed under, the colourway that names it, and the cloth and
   the price. They were once a single run-on string, which is what made this
   strip look like a pile of text — the fix was in the projection that built
   the title, not in clamping harder here. The two-line clamp stays only so
   every card in the rail is the same height. */
.strip { display: flex; gap: 16px; overflow-x: auto; padding-bottom: 8px; }
.strip .look { flex: 0 0 150px; min-width: 0; }
.strip .look .shot { aspect-ratio: 3/4; background: var(--raised); border-radius: var(--r-sm); overflow: hidden; display: grid; place-items: center; }
.strip .look .shot img { width: 100%; height: 100%; object-fit: cover; }
.strip .look .cap { margin-top: 10px; font-size: 12px; line-height: 1.35; }
.strip .look .cap .code {
  display: block; font-family: var(--mono); font-size: 10px;
  letter-spacing: 0.02em; color: var(--fg-faint); margin-bottom: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.strip .look .cap b {
  font-weight: 400; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; min-height: 2.7em;
}
.strip .look .cap span {
  display: block; color: var(--fg-muted); font-size: 11.5px; margin-top: 4px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.section { margin-top: 56px; }
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 16px; }
h2 { font-size: 17px; line-height: 1.3; }
h3 { font-size: 14px; letter-spacing: -0.014em; }
p { margin: 0 0 0.7em; }
code, pre { font-family: var(--mono); font-size: 0.88em; }
code { background: var(--raised); padding: 0.1em 0.34em; border-radius: var(--r-xs); }
pre { background: var(--raised); border: 1px solid var(--line-soft); padding: 12px 14px; border-radius: var(--r-md); overflow-x: auto; }
pre code { background: none; padding: 0; }

/* ── Shell ───────────────────────────────────────────────────────────── */
.shell { min-height: 100vh; display: flex; flex-direction: column; }

.topbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 20px;
  height: 52px; padding: 0 20px;
  background: color-mix(in oklch, var(--bg) 88%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line-soft);
}

.brand { display: flex; align-items: baseline; gap: 9px; text-decoration: none; flex: none; }
.brand b { font-weight: 600; letter-spacing: -0.03em; font-size: 15px; }
.brand span { font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-faint); }

.nav { display: flex; gap: 2px; margin-left: 6px; }
.nav a {
  display: inline-flex; align-items: center; height: 28px; padding: 0 11px;
  border-radius: var(--r-sm); font-size: 13px; color: var(--fg-muted);
  text-decoration: none; transition: background 140ms ease-out, color 140ms ease-out;
}
.nav a:hover { background: var(--raised); color: var(--fg); }
.nav a[aria-current="page"] { background: var(--raised); color: var(--fg); font-weight: 500; }

.topbar .spacer { flex: 1; }

/* Flex and grid children hold their own content hostage unless told they may
   shrink. This is the single most common cause of a page that scrolls
   sideways on a phone. */
.nav, .msg, .msg .body, .dept, .door, .piece, .look, .chip, .card, .figures > div,
.panels > *, .row > label.field, .tool-row, .strip .look .cap { min-width: 0; }
.msg .body, .dept-about, .door-a, .cap, .hint { overflow-wrap: anywhere; }

.who {
  display: inline-flex; align-items: center; gap: 8px; height: 28px;
  padding: 0 4px 0 10px; border-radius: var(--r-sm); background: transparent;
  border: 1px solid transparent; color: var(--fg-muted); font: inherit; font-size: 13px;
  cursor: pointer; text-decoration: none;
}
.who:hover { border-color: var(--line); color: var(--fg); }
.avatar {
  width: 22px; height: 22px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  background: var(--fg); color: var(--bg);
  font-size: 10px; font-weight: 600; letter-spacing: 0.02em;
}

.page { flex: 1; width: 100%; max-width: 1200px; margin: 0 auto; padding: 44px 28px 96px; }
/* Sign-in is the one exception: a single column of form has no business
   being 1200px wide. Every other surface shares the measure. */
.page.narrow { max-width: 780px; }
.page.wide { max-width: 1200px; }

/* ── Controls ────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  height: 32px; padding: 0 13px; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--surface); color: var(--fg);
  font: inherit; font-size: 13px; font-weight: 480; cursor: pointer;
  transition: background 140ms ease-out, border-color 140ms ease-out, transform 90ms ease-out;
}
.btn:hover { background: var(--raised); }
.btn:active { transform: translateY(0.5px); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn.primary { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.btn.primary:hover { background: oklch(0.32 0 0); }
:root[data-theme="dark"] .btn.primary:hover { background: oklch(0.86 0 0); }
.btn.ghost { border-color: transparent; background: transparent; color: var(--fg-muted); }
.btn.ghost:hover { background: var(--raised); color: var(--fg); }
.btn.sm { height: 26px; padding: 0 9px; font-size: 12px; }
.btn.icon { width: 32px; padding: 0; }

/* Every text-ish input, however it was written. `input[type=text]` does not
   match `<input>` with no type attribute — which is most of them — so half
   the fields on the Creator page rendered as bare browser boxes. */
input:not([type=checkbox]):not([type=radio]):not([type=file]), select, textarea {
  font: inherit; color: var(--fg); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 7px 10px; width: 100%;
  transition: border-color 140ms ease-out, box-shadow 140ms ease-out;
}
input:focus-visible, select:focus-visible, textarea:focus-visible, .btn:focus-visible, .dept:focus-visible, .door:focus-visible {
  outline: none;
  border-color: var(--accent-line);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
::placeholder { color: var(--fg-faint); }
label.field { display: block; margin-bottom: 14px; }
label.field > span { display: block; margin-bottom: 5px; font-size: 12px; color: var(--fg-muted); }

/* ── Scrollbars ───────────────────────────────────────────────────────────
   A platform scrollbar is the one piece of chrome a design never gets asked
   about, and it is the one that gives the house away: grey gutters, inset
   bevels, a different shape on every machine. So every scroller in the estate
   wears the same hairline instead.

   Both syntaxes are needed and they are not interchangeable. The standard
   `scrollbar-width`/`scrollbar-color` pair is what Firefox and Chrome 121+
   read, but it offers two colours and no geometry. The ::-webkit- pseudos are
   what Safari still reads and they allow the track to be nothing at all.
   Declaring both means one appearance everywhere rather than two. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--scroll-thumb) transparent;
}
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--scroll-thumb);
  border-radius: 999px;
  /* A transparent border clipped to the padding box is how a thin thumb gets
     breathing room without a visible track around it. */
  border: 3px solid transparent;
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--scroll-thumb-hover); background-clip: padding-box; }
::-webkit-scrollbar-corner { background: transparent; }

/* Where a scroller is small, the bar is thinner still, so it reads as a rule
   rather than as a control sitting on top of the content. */
.brief-out, .scroll-x, .strip, pre, .msg .body { scrollbar-width: thin; }
.brief-out::-webkit-scrollbar, .strip::-webkit-scrollbar { width: 6px; height: 6px; }
.brief-out::-webkit-scrollbar-thumb, .strip::-webkit-scrollbar-thumb { border-width: 2px; }

/* ── Surfaces ────────────────────────────────────────────────────────── */
.card {
  background: var(--surface); border: 1px solid var(--line-soft);
  border-radius: var(--r-md); padding: 18px;
}
.card.plain { border: 0; border-top: 1px solid var(--line); border-radius: 0; padding: 18px 0; }
.card.pad-lg { padding: 22px; }
.grid { display: grid; gap: 12px; }

/* ── A brief ──────────────────────────────────────────────────────────────
   A brief is as long as the day is eventful, so its body is given a fixed
   measure and its own scroll. The alternative — letting it run — makes one
   busy morning stretch the card past the fold and push everything under it
   off the screen. The card keeps its shape; the reader keeps the whole text. */
.card[data-brief] { display: flex; flex-direction: column; }
.brief-out {
  /* Reading size, not label size. A brief is prose somebody reads start to
     finish; the quiet comes from ink and tracking elsewhere, not from
     shrinking the one thing on this card meant to be read. */
  font-size: 14px; line-height: 1.6;
  flex: 1; min-height: 0; max-height: 22rem;
  overflow-y: auto; overscroll-behavior: contain;
  /* A scroll with a hard edge looks like a crop. The fade says "there is more"
     without a scrollbar having to be visible to say it. */
  mask-image: linear-gradient(to bottom, #000 calc(100% - 20px), transparent);
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 20px), transparent);
  padding-right: 4px;
}
.brief-out:not(.is-scrollable) { mask-image: none; -webkit-mask-image: none; }
.brief-foot { margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--line-soft); }
.brief-foot:empty { display: none; }

/* The blocks a brief is made of. Margins carry the spacing, so the renderer
   never has to emit a <br> and never double-spaces a list. */
.md-p { margin: 0 0 9px; }
.md-p:last-child { margin-bottom: 0; }
.md-h {
  margin: 16px 0 7px; font-size: 11px; font-weight: 500;
  letter-spacing: 0.07em; text-transform: uppercase; color: var(--fg-muted);
}
.md-h:first-child { margin-top: 0; }
.md-list { margin: 0 0 10px; padding-left: 16px; list-style: none; }
.md-list > li { position: relative; margin-bottom: 5px; }
.md-list > li::before {
  content: "—"; position: absolute; left: -16px; color: var(--fg-muted);
}
.md-list > li:last-child { margin-bottom: 0; }

/* Panels of unequal height in a grid with align-items:start leave holes —
   a grid pretending to be masonry, which reads as cards dropping out of
   place. Panels stretch to their row instead, and the content inside sits
   at the top where it belongs. */
.panels { display: grid; gap: 14px; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: stretch; }
.panels > * { display: flex; flex-direction: column; }
.panels > * > .body { flex: 1; }
@media (max-width: 900px) { .panels { grid-template-columns: 1fr; } }

/* A row that puts a field and its button on one line. */
.row { display: flex; gap: 10px; align-items: flex-end; }
.row > label.field { flex: 1; margin-bottom: 0; }

/* The drop target: an invitation, not an empty room. */
.dropzone {
  border: 1px dashed var(--line); border-radius: var(--r-md); background: var(--surface);
  padding: 26px 20px; text-align: center;
  transition: border-color 150ms ease-out, background 150ms ease-out;
}
.dropzone:hover { border-color: var(--fg-faint); }
.dropzone.over { border-color: var(--fg); background: var(--raised); }
.dropzone svg { color: var(--fg-faint); margin-bottom: 10px; }
.grid.cols-2 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.grid.cols-3 { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }

/* Departments: exactly four across on a wide desktop and two on a tablet, so
   eight cards always fill their rows. auto-fit would pick five at some widths
   and leave three stranded, which is what "the layout breaks" looks like. */
.depts { display: grid; gap: 12px; grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1100px) { .depts { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 820px)  { .depts { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px)  { .depts { grid-template-columns: 1fr; } }
.grid.cols-4 { grid-template-columns: repeat(auto-fit, minmax(165px, 1fr)); }

.badge {
  display: inline-flex; align-items: center; gap: 5px; height: 20px; padding: 0 7px;
  border-radius: var(--r-xs); font-size: 11px; font-weight: 500;
  background: var(--raised); color: var(--fg-muted); border: 1px solid var(--line-soft);
}
.badge.read { color: var(--ok); border-color: color-mix(in oklch, var(--ok) 30%, transparent); background: color-mix(in oklch, var(--ok) 8%, transparent); }
.badge.write { color: var(--warn); border-color: color-mix(in oklch, var(--warn) 34%, transparent); background: color-mix(in oklch, var(--warn) 9%, transparent); }
.badge.bad { color: var(--bad); border-color: color-mix(in oklch, var(--bad) 30%, transparent); background: color-mix(in oklch, var(--bad) 8%, transparent); }

hr { border: 0; border-top: 1px solid var(--line-soft); margin: 22px 0; }

table { border-collapse: collapse; width: 100%; font-size: 13px; }
th, td { text-align: left; padding: 7px 12px 7px 0; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
th { font-size: 10px; font-weight: 550; letter-spacing: 0.09em; text-transform: uppercase; color: var(--fg-faint); }
tbody tr:last-child td { border-bottom: 0; }

/* ── Department cards ────────────────────────────────────────────────── */
.dept {
  display: block; width: 100%; text-align: left; cursor: pointer;
  background: var(--surface); border: 1px solid var(--line-soft);
  border-radius: var(--r-md); padding: 14px 15px; color: inherit; font: inherit;
  transition: border-color 140ms ease-out, transform 120ms ease-out, box-shadow 140ms ease-out;
}
.dept:hover { border-color: var(--line); transform: translateY(-1px); box-shadow: var(--shadow-sm); }
/* Selected is a whole border in the ink colour — even on all four sides. A
   thickened left edge made the card look nudged out of the grid rather than
   chosen. */
.dept[aria-pressed="true"] { border-color: var(--fg); }
.dept .dept-name { display: flex; align-items: center; gap: 8px; font-weight: 530; font-size: 13.5px; }
.dept .dept-about { margin-top: 3px; color: var(--fg-muted); font-size: 12.5px; line-height: 1.45; }
.dept .dept-icon { width: 15px; height: 15px; flex: none; color: var(--fg-faint); }
.dept:hover .dept-icon, .dept[aria-pressed="true"] .dept-icon { color: var(--accent-ink); }

/* ── Conversation ────────────────────────────────────────────────────── */
.convo { display: flex; flex-direction: column; gap: 22px; padding: 4px 0 8px; }

.msg { max-width: 72ch; }
.msg.from-user { margin-left: auto; max-width: 60ch; }
.msg.from-user .bubble {
  background: var(--raised); border: 1px solid var(--line-soft);
  border-radius: var(--r-md); padding: 9px 13px; white-space: pre-wrap;
}
.msg .role { margin-bottom: 6px; }
.msg .body { white-space: pre-wrap; overflow-wrap: anywhere; }
.msg .body > *:last-child { margin-bottom: 0; }
.msg .body table { margin: 10px 0; }
.msg .body th, .msg .body td { padding-right: 18px; }
.msg .meta { margin-top: 8px; font-size: 11.5px; color: var(--fg-faint); display: flex; gap: 10px; align-items: center; }

/* Tool rows — the four states, collapsed unless they failed. */
.tool-row {
  display: flex; align-items: center; gap: 9px; padding: 6px 10px;
  border: 1px solid var(--line-soft); border-radius: var(--r-sm);
  background: var(--surface); font-size: 12.5px; color: var(--fg-muted);
  margin-bottom: 8px;
}
.tool-row .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--fg-faint); flex: none; }
.tool-row.running .dot { background: var(--accent); animation: pulse 1.1s ease-in-out infinite; }
.tool-row.done .dot { background: var(--ok); }
.tool-row.error { border-color: color-mix(in oklch, var(--bad) 30%, transparent); color: var(--bad); }
.tool-row.error .dot { background: var(--bad); }
.tool-row .name { font-family: var(--mono); font-size: 11.5px; color: var(--fg); }

@keyframes pulse { 0%,100% { opacity: 1 } 50% { opacity: 0.3 } }

.shimmer {
  display: inline-block; color: transparent;
  background: linear-gradient(90deg, var(--fg-faint) 25%, var(--fg-muted) 50%, var(--fg-faint) 75%);
  background-size: 200% 100%; -webkit-background-clip: text; background-clip: text;
  animation: sweep 1.6s linear infinite;
}
@keyframes sweep { to { background-position: -200% 0 } }

/* ── Composer ────────────────────────────────────────────────────────── */
.composer {
  position: sticky; bottom: 0;
  background: var(--bg); padding-top: 10px;
}
.composer-box {
  border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface);
  transition: border-color 140ms ease-out, box-shadow 140ms ease-out;
}
.composer-box:focus-within { border-color: var(--accent-line); box-shadow: 0 0 0 3px var(--accent-soft); }
.composer-box.dragging { border-color: var(--accent); background: var(--accent-soft); }

.attach-row { display: flex; flex-wrap: wrap; gap: 6px; padding: 9px 10px 0; }
.chip {
  display: inline-flex; align-items: center; gap: 7px; height: 27px; padding: 0 6px 0 9px;
  border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--raised);
  font-size: 12px; max-width: 240px;
}
.chip .chip-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chip .chip-meta { color: var(--fg-faint); font-size: 11px; flex: none; }
.chip .chip-x {
  width: 16px; height: 16px; border: 0; background: none; color: var(--fg-faint);
  cursor: pointer; border-radius: var(--r-xs); display: grid; place-items: center; padding: 0;
  opacity: 0; transition: opacity 120ms ease-out;
}
.chip:hover .chip-x { opacity: 1; }
.chip .chip-x:hover { background: var(--line); color: var(--fg); }
.chip img { width: 19px; height: 19px; border-radius: var(--r-xs); object-fit: cover; flex: none; }

.composer textarea {
  border: 0; background: transparent; padding: 11px 13px 4px; resize: none;
  min-height: 46px; max-height: 40vh; width: 100%; font-size: 14px; line-height: 1.5;
}
.composer textarea:focus-visible { outline: none; box-shadow: none; border: 0; }

.composer-foot { display: flex; align-items: center; gap: 7px; padding: 6px 8px 8px 10px; }
.composer-foot .spacer { flex: 1; }
.send {
  width: 30px; height: 30px; border-radius: 50%; border: 0; flex: none;
  background: var(--fg); color: var(--bg); cursor: pointer;
  display: grid; place-items: center;
  transition: background 140ms ease-out, transform 90ms ease-out;
}
.send:hover { background: oklch(0.34 0 0); }
.send:disabled { opacity: 0.35; cursor: not-allowed; }
.send.streaming { background: var(--accent); }
:root[data-theme="dark"] .send:hover { background: oklch(0.84 0 0); }

.hint { font-size: 11.5px; color: var(--fg-faint); }
.hint b { font-weight: 500; color: var(--fg-muted); }

.suggest { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.suggest button {
  border: 1px solid var(--line-soft); background: var(--surface); color: var(--fg-muted);
  border-radius: 100px; padding: 5px 12px; font: inherit; font-size: 12.5px; cursor: pointer;
  transition: border-color 140ms ease-out, color 140ms ease-out;
}
.suggest button:hover { border-color: var(--accent-line); color: var(--fg); }

/* ── Data ────────────────────────────────────────────────────────────── */
.metric { display: flex; flex-direction: column; gap: 3px; }
.metric .metric-value { font-size: 26px; font-weight: 500; letter-spacing: -0.03em; line-height: 1.1; }
.metric .metric-label { font-size: 11px; color: var(--fg-muted); }

.chart { width: 100%; overflow: visible; }
.chart .axis { stroke: var(--line); stroke-width: 1; }
.chart .grid-line { stroke: color-mix(in oklch, var(--line) 60%, transparent); stroke-width: 1; }
.chart text { fill: var(--fg-muted); font-size: 10.5px; font-family: var(--sans); }
.chart .bar { transition: opacity 140ms ease-out; }
.chart .bar:hover { opacity: 0.78; }

.scroll-x { overflow-x: auto; }

/* Product results: in fashion the image is the primary key, so results are a
   grid of pieces with their numbers attached, never a table with a thumbnail
   column bolted on. */
.pieces { display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 12px; margin: 10px 0; }
.piece { border: 1px solid var(--line-soft); border-radius: var(--r-md); overflow: hidden; background: var(--surface); }
.piece .shot { aspect-ratio: 3/4; background: var(--raised); display: grid; place-items: center; color: var(--fg-faint); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; }
.piece .shot img { width: 100%; height: 100%; object-fit: cover; }
.piece .about { padding: 9px 10px; }
.piece .about .t {
  font-size: 12.5px; line-height: 1.35; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.piece .about .s { margin-top: 3px; font-size: 11.5px; color: var(--fg-muted); }

.empty { text-align: center; padding: 54px 20px; color: var(--fg-muted); }
.empty h2 { margin-bottom: 6px; color: var(--fg); }
.empty p { max-width: 46ch; margin: 0 auto 4px; font-size: 13px; }

.notice {
  border: 1px solid var(--accent-line); background: var(--accent-soft);
  border-radius: var(--r-md); padding: 11px 14px; font-size: 13px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

@media (max-width: 900px) {
  /* Six destinations will not fit a phone, so the navigation scrolls rather
     than wrapping into the header or hiding behind a hamburger nobody opens.
     The scrollbar is hidden; the overflow is the affordance — and it is
     contained, so it never widens the page behind it. */
  .topbar { gap: 12px; padding: 0 14px; overflow: hidden; }
  .brand span { display: none; }
  .nav { overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none; flex: 1; margin-left: 0; }
  .nav::-webkit-scrollbar { display: none; }
  .nav a { flex: none; }
  .topbar .spacer { display: none; }
  .who span:first-child { display: none; }
  .page { padding: 26px 16px 56px; }
  h1.display, .display { font-size: clamp(28px, 8vw, 38px); }
  .lede { font-size: 15px; }
  .section { margin-top: 38px; }
  /* Two-column page layouts become one column, in reading order. */
  .page > .grid[style*="1.55fr"] { grid-template-columns: 1fr !important; gap: 32px !important; }
  .doors { grid-template-columns: 1fr; }
  .door { border-right: 0; border-bottom: 1px solid var(--line-soft); padding-right: 0; }
  .door:last-child { border-bottom: 0; }
  .figures > div { padding-left: 14px; padding-right: 14px; }
  .msg, .msg.from-user { max-width: 100%; }
  .row { flex-direction: column; align-items: stretch; }
  .row > .btn { width: 100%; }
  .strip .look { flex: 0 0 132px; }

  /* An attention row puts its source label beneath the text rather than
     squeezing the sentence into half a column. */
  #attention .card { flex-wrap: wrap; }
  #attention .card > .eyebrow { margin-top: 6px; }
  #attention .card > .spacer { display: none; }
}

@media (max-width: 520px) {
  .figures { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Two columns: the left-hand cell of each row is the one against the page
     margin now, so it is the one that gives its left padding back. */
  .figures > div:nth-child(2n) { border-right: 0; padding-right: 0; }
  .figures > div:nth-child(2n+1) { padding-left: 0; }
  .grid.cols-2, .grid.cols-3, .grid.cols-4 { grid-template-columns: 1fr; }
  .composer-foot .hint { display: none; }
  table { font-size: 12.5px; }
}

/* ── Production, Catalog and Discover ────────────────────────────────────
   Three surfaces that show a lot of structured fact at once, so almost
   everything here is about keeping density legible: hairlines instead of
   boxes, one weight of ink for the fact and a lighter one for its label. */

.head-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; flex-wrap: wrap; }

.freshness { display: flex; align-items: center; gap: 8px; font-size: 12.5px; padding-top: 4px; }
.dot { width: 6px; height: 6px; border-radius: 50%; background: var(--fg-faint); flex: none; }
.dot-ok { background: var(--ok); }
.dot-warn { background: var(--warn); }

.tone-bad { color: var(--bad); }
.tone-warn { color: var(--warn); }
.tone-mute { color: var(--fg-muted); }

/* ── Exceptions ─────────────────────────────────────────────────────────
   Ranked by what it costs to ignore. The severity is a rule down the left
   rather than a coloured pill, so a page of them reads as a list and not as
   a bag of badges — and the words carry the severity too, never the hue alone. */
.exc-group { margin-bottom: 26px; }
.exc-group:last-child { margin-bottom: 0; }
.exc {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 11px 0; border-bottom: 1px solid var(--line-soft);
}
.exc:last-child { border-bottom: 0; }
.exc-rule { width: 2px; align-self: stretch; background: currentColor; border-radius: 1px; flex: none; }
.exc-subject { font-size: 13.5px; overflow-wrap: anywhere; }
.exc-detail { font-size: 12.5px; color: var(--fg-muted); margin-top: 2px; overflow-wrap: anywhere; }
.exc-kind {
  margin-left: auto; font-family: var(--mono); font-size: 10.5px;
  color: var(--fg-faint); white-space: nowrap; padding-top: 2px;
}

/* ── The delivery plan ──────────────────────────────────────────────────
   A shared horizontal time axis: every bar is measured against the same
   scale, so two factories landing in the same week is a thing you see
   rather than a pair of dates you have to compare in your head. */
.tl { --tl-label: 190px; }
.tl-row, .tl-axis { display: grid; grid-template-columns: var(--tl-label) minmax(0, 1fr); gap: 14px; align-items: center; }
.tl-row { padding: 5px 0; }
.tl-row:hover .tl-bar { filter: brightness(0.88); }
.tl-label { min-width: 0; font-size: 12px; line-height: 1.25; }
.tl-doc { display: block; font-family: var(--mono); font-size: 11px; color: var(--fg); }
.tl-maker { display: block; color: var(--fg-muted); font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.tl-axis { padding-bottom: 10px; margin-bottom: 6px; border-bottom: 1px solid var(--line); }
.tl-track { position: relative; height: 20px; }
.tl-axis .tl-track { height: 14px; }
.tl-tick {
  position: absolute; top: 0; font-size: 10.5px; color: var(--fg-faint);
  transform: translateX(-50%); white-space: nowrap;
}
/* Today is a rule through the whole plot, not a marker on one row. */
.tl-today { position: absolute; top: -4px; bottom: -9999px; width: 1px; background: var(--accent); opacity: 0.55; }

.tl-bar { position: absolute; top: 5px; height: 10px; border-radius: 2px; min-width: 3px; }
.tl-confirmed   { background: var(--chart-1); }
.tl-unconfirmed { background: var(--fg-faint); }
.tl-late        { background: var(--bad); }
.tl-when {
  position: absolute; top: 3px; font-size: 10.5px; color: var(--fg-faint);
  white-space: nowrap; pointer-events: none;
}

.legend { display: flex; flex-wrap: wrap; gap: 18px; margin-top: 20px; padding-top: 14px; border-top: 1px solid var(--line-soft); font-size: 12px; color: var(--fg-muted); }
.legend span { display: flex; align-items: center; gap: 7px; }
.legend .sw { width: 14px; height: 8px; border-radius: 2px; flex: none; }
.legend .sw-line { width: 1px; height: 12px; background: var(--accent); flex: none; }

/* ── Rows that open something ───────────────────────────────────────────── */
.row-link { cursor: pointer; }
.row-link:hover td { background: var(--raised); }

/* ── The drawer ─────────────────────────────────────────────────────────
   A detail view that does not lose the page behind it. It arrives on a
   decelerating curve whose control points all sit inside [0,1], so it cannot
   overshoot — the entrance runs slightly longer than the exit, which is what
   makes a panel read as placed rather than thrown. */
/* The panel is closed by `hidden`, and a bare `.drawer { display: flex }`
   silently defeats that: a class selector outranks the user-agent's
   [hidden] { display: none }, so the overlay painted over every one of these
   pages from first load with no way to dismiss it. Stating the closed case
   explicitly is the fix, and it belongs first so nothing below can undo it. */
.drawer[hidden] { display: none; }
.drawer { position: fixed; inset: 0; z-index: 60; background: oklch(0.16 0 0 / 0.28); display: flex; justify-content: flex-end; }
.drawer-panel {
  width: min(720px, 100%); background: var(--surface); height: 100%;
  display: flex; flex-direction: column; border-left: 1px solid var(--line);
  animation: drawer-in 300ms cubic-bezier(0.05, 0.7, 0.1, 1);
}
@keyframes drawer-in { from { transform: translateX(18px); opacity: 0; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .drawer-panel { animation: none; } }
.drawer-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
  padding: 22px 26px; border-bottom: 1px solid var(--line); flex: none;
}
.drawer-body { padding: 26px; overflow-y: auto; flex: 1; min-height: 0; }
.drawer-hero { display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: 22px; align-items: start; }
.drawer-hero .shot { aspect-ratio: 3/4; background: var(--raised); border-radius: var(--r-sm); overflow: hidden; display: grid; place-items: center; }
.drawer-hero .shot img { width: 100%; height: 100%; object-fit: cover; }

table.facts { width: 100%; border-collapse: collapse; font-size: 13px; }
table.facts th {
  text-align: left; font-weight: 400; color: var(--fg-muted); font-size: 12px;
  padding: 7px 14px 7px 0; white-space: nowrap; vertical-align: top; width: 1%;
}
table.facts td { padding: 7px 0; border-bottom: 1px solid var(--line-soft); }
table.facts tr:last-child td, table.facts tr:last-child th { border-bottom: 0; }

/* ── Search and facet chips ─────────────────────────────────────────────── */
.searchbar { display: flex; gap: 10px; margin-top: 30px; }
.searchbar input { flex: 1; min-width: 0; }
.chips { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 14px; margin-bottom: 4px; }
.chip {
  font: inherit; font-size: 12px; cursor: pointer;
  background: var(--surface); color: var(--fg-muted);
  border: 1px solid var(--line); border-radius: 999px; padding: 5px 12px;
  transition: border-color 160ms cubic-bezier(0, 0, 0.3, 1), color 160ms cubic-bezier(0, 0, 0.3, 1);
}
.chip:hover { border-color: var(--fg-faint); color: var(--fg); }
.chip.on { background: var(--fg); border-color: var(--fg); color: var(--bg); }
.chip .chip-n { opacity: 0.5; margin-left: 3px; }

/* ── Pieces ─────────────────────────────────────────────────────────────── */
.pieces { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 18px; }
.piece-link { cursor: pointer; }
.piece .shot { aspect-ratio: 3/4; background: var(--raised); display: grid; place-items: center; }
.piece .shot img { width: 100%; height: 100%; object-fit: cover; }
.shot-empty { font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-faint); }
.piece .about { padding: 11px 12px 13px; font-size: 12px; line-height: 1.35; }
.piece .about .code {
  display: block; font-family: var(--mono); font-size: 10px;
  color: var(--fg-faint); margin-bottom: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.piece .about b {
  font-weight: 400; display: -webkit-box; -webkit-line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere;
}
.piece .about > span {
  display: block; color: var(--fg-muted); font-size: 11.5px; margin-top: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.piece .gap-flag { display: block; margin-top: 5px; font-size: 10.5px; color: var(--fg-faint); }

.gap-card .metric-value { font-size: 26px; color: var(--accent-ink); }

/* ── Plain bars ─────────────────────────────────────────────────────────
   A magnitude comparison that does not need an axis: the label reads, the
   bar ranks, the number is exact. Cheaper than a chart and easier to scan. */
.bars { display: flex; flex-direction: column; gap: 7px; }
.bar-row { display: grid; grid-template-columns: minmax(0, 1fr) 96px 44px; gap: 12px; align-items: center; font-size: 12.5px; }
.bar-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bar-track { height: 6px; background: var(--raised); border-radius: 999px; overflow: hidden; }
.bar-fill { display: block; height: 100%; background: var(--chart-1); border-radius: 999px; }
.bar-value { text-align: right; color: var(--fg-muted); }

/* ── Discover: the drop target ────────────────────────────────────────────
   Reuses the .dropzone the playground already defines — same affordance, so
   it should not be a second thing that merely looks similar. Only the parts
   specific to a photograph search are added. */
.dropzone { cursor: pointer; }
.dropzone input[type="file"] { display: none; }
.dropzone .dz-title { font-size: 13.5px; }
.dropzone .dz-hint { font-size: 12px; color: var(--fg-muted); margin-top: 5px; }
.dz-preview { max-height: 190px; border-radius: var(--r-sm); margin-top: 14px; }

/* Two ways into the same catalogue, side by side. */
.finder { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: 26px; align-items: start; margin-top: 30px; }

/* ── Creator: the bench ─────────────────────────────────────────────────── */
.bench { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: 30px; align-items: start; margin-top: 30px; }
.ref-slot {
  border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 14px; display: flex; gap: 13px; align-items: center;
}
.ref-slot .shot { width: 54px; height: 72px; flex: none; background: var(--raised); border-radius: var(--r-xs); overflow: hidden; display: grid; place-items: center; }
.ref-slot .shot img { width: 100%; height: 100%; object-fit: cover; }
.ref-slot .ref-name { font-size: 13px; }
.ref-slot .ref-meta { font-size: 11.5px; color: var(--fg-muted); margin-top: 2px; }
.out-frame {
  border: 1px solid var(--line-soft); border-radius: var(--r-md);
  background: var(--raised); min-height: 280px; display: grid; place-items: center;
  overflow: hidden; padding: 16px;
}
.out-frame img, .out-frame video { max-width: 100%; max-height: 460px; border-radius: var(--r-sm); }
.route {
  font-family: var(--mono); font-size: 11.5px; line-height: 1.6;
  background: var(--raised); border-radius: var(--r-sm); padding: 12px 14px;
  margin-top: 14px; overflow-x: auto;
}
.seg { display: inline-flex; border: 1px solid var(--line); border-radius: var(--r-sm); overflow: hidden; }
.seg button {
  font: inherit; font-size: 12.5px; background: var(--surface); color: var(--fg-muted);
  border: 0; padding: 7px 14px; cursor: pointer;
}
.seg button + button { border-left: 1px solid var(--line); }
.seg button[aria-pressed="true"] { background: var(--fg); color: var(--bg); }

@media (max-width: 900px) {
  /* The timeline keeps its axis but gives the labels less room. */
  .tl { --tl-label: 104px; }
  .tl-when { display: none; }
  .drawer-hero { grid-template-columns: 1fr; }
  .drawer-hero .shot { max-width: 190px; }
  .drawer-head, .drawer-body { padding: 18px; }
  .pieces { grid-template-columns: repeat(auto-fill, minmax(136px, 1fr)); gap: 12px; }
  .searchbar { flex-direction: column; }
  .searchbar .btn { width: 100%; }
  .bar-row { grid-template-columns: minmax(0, 1fr) 60px 40px; }
  .finder, .bench { grid-template-columns: 1fr; gap: 24px; }
}
