/* ==========================================================================
   Mauqe V2 — Application shell
   The persistent frame: top bar, sidebar, content well, and the three-pane
   builder workspace. Screens live inside this frame and never redefine it.
   ========================================================================== */

.app {
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
  grid-template-rows: var(--topbar-h) minmax(0, 1fr);
  grid-template-areas:
    "brand  topbar"
    "side   main";
  min-block-size: 100dvh;
}
.app[data-sidebar="collapsed"] { grid-template-columns: var(--sidebar-w-sm) minmax(0, 1fr); }

/* ---- Brand corner ---------------------------------------------------- */
.app-brand {
  grid-area: brand;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding-inline: var(--s-4);
  background: var(--bg-surface);
  border-inline-end: 1px solid var(--border);
  border-block-end: 1px solid var(--border);
}
.app-brand a { display: flex; align-items: center; gap: var(--s-3); min-width: 0; color: var(--fg-strong); }
.app-brand a:hover { text-decoration: none; }
.brand-mark {
  display: flex; align-items: center; justify-content: center;
  inline-size: 30px; block-size: 30px;
  border-radius: var(--r-md);
  background: linear-gradient(135deg, var(--brand-500), var(--brand-700));
  color: var(--brand-on);
  font-weight: var(--fw-bold);
  font-size: var(--t-sm);
  flex: 0 0 auto;
  box-shadow: var(--sh-2);
}
.brand-name { font-weight: var(--fw-semi); font-size: var(--t-md); letter-spacing: var(--tracking-tight); }
.app[data-sidebar="collapsed"] .brand-name { display: none; }

/* ---- Top bar --------------------------------------------------------- */
.app-topbar {
  grid-area: topbar;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding-inline: var(--s-4) var(--s-4);
  background: var(--bg-surface);
  border-block-end: 1px solid var(--border);
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-sticky);
}
.topbar-title { display: flex; flex-direction: column; min-width: 0; gap: 1px; }
.topbar-title h1 { font-size: var(--t-md); font-weight: var(--fw-semi); }
.topbar-title .sub { font-size: var(--t-xs); color: var(--fg-muted); }
.topbar-actions { display: flex; align-items: center; gap: var(--s-2); margin-inline-start: auto; }

/* ---- Sidebar --------------------------------------------------------- */
.app-sidebar {
  grid-area: side;
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  padding: var(--s-3) var(--s-2) var(--s-4);
  background: var(--bg-surface);
  border-inline-end: 1px solid var(--border);
  overflow-y: auto;
  position: sticky;
  inset-block-start: var(--topbar-h);
  block-size: calc(100dvh - var(--topbar-h));
}

.nav-group { display: flex; flex-direction: column; gap: 1px; }
.nav-group + .nav-group { margin-block-start: var(--s-4); }
.nav-title {
  padding: var(--s-2) var(--s-3) var(--s-1);
  font-size: var(--t-2xs);
  font-weight: var(--fw-semi);
  /* These name the groups of the main navigation, so they are read rather
     than glanced at; --fg-subtle measures 4.3:1 at 11px. */
  color: var(--fg-muted);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}
[dir="rtl"] .nav-title { letter-spacing: 0; }
.app[data-sidebar="collapsed"] .nav-title { text-align: center; font-size: 0; padding-block: var(--s-2); }
.app[data-sidebar="collapsed"] .nav-title::after {
  content: ""; display: block; height: 1px; background: var(--border); margin-inline: var(--s-2);
}

.nav-item {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-block-size: 36px;
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-md);
  font-size: var(--t-sm);
  font-weight: var(--fw-medium);
  color: var(--fg-muted);
  transition: background var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out);
  position: relative;
}
.nav-item:hover { background: var(--bg-hover); color: var(--fg-strong); text-decoration: none; }
.nav-item svg { inline-size: 18px; block-size: 18px; flex: 0 0 auto; }
.nav-item .label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-item[aria-current="page"], .nav-item.is-active {
  background: var(--brand-bg);
  color: var(--brand-fg);
  font-weight: var(--fw-semi);
}
.nav-item[aria-current="page"]::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  inset-block: 20%;
  inline-size: 3px;
  border-radius: var(--r-full);
  background: var(--brand-solid);
}
.app[data-sidebar="collapsed"] .nav-item { justify-content: center; padding-inline: 0; }
.app[data-sidebar="collapsed"] .nav-item .label,
.app[data-sidebar="collapsed"] .nav-item .count { display: none; }

/* ---- Main well ------------------------------------------------------- */
.app-main { grid-area: main; min-inline-size: 0; display: flex; flex-direction: column; }

/* An app being run wears its own theme, and only here.
   layout/base.html writes data-mq-skin on this element and emits a stylesheet
   that re-points the tokens inside it (httpx.RuntimeSkinScope); the chrome is
   made of siblings, so it keeps the workspace palette.

   These five declarations are the ones <body> already makes from tokens a
   theme is allowed to move, restated where the theme starts. They are needed
   because inheritance passes the *resolved* value down, not the variable: text
   inside this region would otherwise be the colour and the face body computed
   from the workspace's tokens, and a themed app would show its cards and its
   accent in the workspace's ink and the workspace's type. Everything below
   this element reads its own tokens at the element that uses them and needs no
   help. Nothing else about the well changes. */
.app-main[data-mq-skin] {
  background-color: var(--bg-app);
  background-image: var(--bg-app-image);
  /* Same reason as body: a wash stays put behind a scrolling page and a grid
     does not slide under the content. */
  background-attachment: fixed;
  color: var(--fg-default);
  font-family: var(--font-sans);
  line-height: var(--lh-base);
}

/* ---- Mobile: sidebar becomes an off-canvas drawer + bottom tab bar ---- */

/* The drawer's backdrop. It exists in the markup on every page (layout/base.html)
   and shows itself only at drawer widths, because a backdrop has to be a real
   element: it was a `::after` on `.app`, and a pseudo-element cannot be the
   target of a click. A tap on it reported the shell as the target, no handler
   matched, and the drawer stayed put. */
.app-scrim { display: none; }

@media (max-width: 900px) {
  .app {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: var(--topbar-h) minmax(0, 1fr);
    grid-template-areas: "topbar" "main";
    padding-block-end: 58px; /* room for the bottom bar */
  }
  .app-brand { display: none; }
  .app-sidebar {
    position: fixed;
    /* Below the top bar, not over it. The drawer used to start at the top of
       the viewport and cover the very button that opened it, so "press the
       menu button again" — the first dismissal anybody tries — landed on a
       navigation link instead. Leaving the bar visible costs 56px of a panel
       that scrolls anyway and gives the control back. */
    inset-block: var(--topbar-h) 0;
    inset-inline-start: 0;
    z-index: var(--z-drawer);
    inline-size: min(280px, 84vw);
    box-shadow: var(--sh-5);
    transform: translateX(calc(-101% * var(--dir-flip)));
    /* `visibility` is what takes the drawer's links out of the tab order.
       Transform alone leaves eight focusable links parked off-screen, so a
       keyboard user tabs into a menu they cannot see.

       It is switched instantly and held, never interpolated. A duration on
       `visibility` interpolates it discretely, which flips the value at the
       *half-way* point of the move — so for the first half of the opening
       slide the panel was still computed `hidden`, nothing inside it could
       take focus, and moving focus into the drawer as it opened silently did
       nothing. Zero seconds on the way in; zero seconds delayed by the length
       of the slide on the way out, so the links leave the tab order the moment
       the drawer starts closing and the panel stays drawn until it has gone. */
    visibility: hidden;
    transition: transform var(--dur-3) var(--ease-out),
                visibility 0s linear var(--dur-3);
  }
  .app[data-sidebar="open"] .app-sidebar {
    transform: none;
    visibility: visible;
    transition: transform var(--dur-3) var(--ease-out), visibility 0s;
  }
  /* In the drawer the sidebar is the primary navigation and is driven by a
     thumb, so its rows have to clear the touch-target minimum. */
  .app-sidebar .nav-item { min-block-size: var(--tap-min); }

  .app-scrim {
    display: block;
    position: fixed;
    inset-block: var(--topbar-h) 0;
    inset-inline: 0;
    z-index: calc(var(--z-drawer) - 1);
    border: 0;
    padding: 0;
    background: var(--overlay);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--dur-3) var(--ease-out), visibility 0s linear var(--dur-3);
  }
  .app[data-sidebar="open"] .app-scrim {
    opacity: 1;
    visibility: visible;
    transition: opacity var(--dur-3) var(--ease-out), visibility 0s;
  }

  /* The page behind a drawer does not scroll. `data-drawer` is written by
     app.js when the drawer opens at this width and cleared when it closes or
     when the viewport grows past this query. */
  html[data-drawer="open"], html[data-drawer="open"] body { overflow: hidden; }
}

/* Bottom tab bar — the four things people do daily, one thumb away. */
.tabbar {
  display: none;
  position: fixed;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: var(--z-sticky);
  background: var(--bg-surface);
  border-block-start: 1px solid var(--border);
  padding-block-end: env(safe-area-inset-bottom, 0);
}
@media (max-width: 900px) { .tabbar { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; } }
.tabbar a {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-block-size: 56px;
  font-size: var(--t-2xs);
  font-weight: var(--fw-medium);
  /* 11px navigation labels: --fg-subtle measures 4.3:1 here, so the phone's
     primary navigation would be the least legible text on the screen. */
  color: var(--fg-muted);
  position: relative;
}
.tabbar a:hover { text-decoration: none; }
.tabbar a svg { inline-size: 21px; block-size: 21px; }
.tabbar a[aria-current="page"] { color: var(--brand-fg); }
.tabbar .count { position: absolute; inset-block-start: 6px; inset-inline-start: 55%; }

/* ==========================================================================
   Page header — the consistent band at the top of every screen
   ========================================================================== */
.page-head {
  display: flex;
  align-items: flex-start;
  gap: var(--s-4);
  flex-wrap: wrap;
  margin-block-end: var(--s-6);
}
.page-head .titles { min-width: 0; flex: 1 1 320px; }
.page-head h1 { font-size: var(--t-2xl); margin-block-end: var(--s-1); }
.page-head .lede { color: var(--fg-muted); font-size: var(--t-sm); max-inline-size: var(--prose-max); }
.page-head .acts { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }

/* Toolbar strip above lists: search + filters on one side, actions on the other. */
.toolbar {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex-wrap: wrap;
  margin-block-end: var(--s-4);
}
.toolbar .search { flex: 1 1 240px; max-inline-size: 380px; }

/* ==========================================================================
   Builder workspace — three panes: palette | canvas | inspector
   This is the core screen of the product, so it gets first-class layout.
   ========================================================================== */
.workspace {
  display: grid;
  grid-template-columns: var(--palette-w) minmax(0, 1fr) var(--inspector-w);
  grid-template-areas: "palette canvas inspector";
  block-size: calc(100dvh - var(--topbar-h));
  overflow: hidden;
}
/* "closed" and "hidden" are the same thing to the layout, and both have to be
   here: index.js says `closed` for the palette and `hidden` for the inspector,
   and only `hidden` was ever written down. So on a desktop the palette column
   stayed 264px wide whatever anybody pressed — the × in its header and the
   "Add a field" button in the toolbar both did nothing at all — and the canvas
   between the two panes was 428px of a 1032px workspace. */
.workspace[data-palette="hidden"],
.workspace[data-palette="closed"]   { grid-template-columns: 0 minmax(0, 1fr) var(--inspector-w); }
.workspace[data-inspector="hidden"],
.workspace[data-inspector="closed"] { grid-template-columns: var(--palette-w) minmax(0, 1fr) 0; }
.workspace[data-palette="hidden"][data-inspector="hidden"],
.workspace[data-palette="hidden"][data-inspector="closed"],
.workspace[data-palette="closed"][data-inspector="hidden"],
.workspace[data-palette="closed"][data-inspector="closed"] { grid-template-columns: 0 minmax(0, 1fr) 0; }

.ws-palette {
  grid-area: palette;
  display: flex;
  flex-direction: column;
  min-inline-size: 0;
  background: var(--bg-surface);
  border-inline-end: 1px solid var(--border);
  overflow: hidden;
}
.ws-canvas {
  grid-area: canvas;
  min-inline-size: 0;
  overflow-y: auto;
  background: var(--bg-app);
  background-image: radial-gradient(var(--canvas-grid) 1px, transparent 1px);
  background-size: 18px 18px;
  padding: var(--s-6) var(--s-6) var(--s-20);
}
.ws-inspector {
  grid-area: inspector;
  display: flex;
  flex-direction: column;
  min-inline-size: 0;
  background: var(--bg-surface);
  border-inline-start: 1px solid var(--border);
  overflow: hidden;
}

/* Shared pane chrome */
.pane-hd {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-4);
  border-block-end: 1px solid var(--border);
  flex: 0 0 auto;
  min-block-size: 48px;
}
.pane-hd h2 { font-size: var(--t-sm); font-weight: var(--fw-semi); }
.pane-bd { flex: 1 1 auto; overflow-y: auto; padding: var(--s-3); }
.pane-ft { flex: 0 0 auto; padding: var(--s-3) var(--s-4); border-block-start: 1px solid var(--border); background: var(--bg-subtle); }

/* Builder panes stack on narrow screens: canvas is primary, the other two
   become slide-over sheets triggered from the toolbar. */
@media (max-width: 1100px) {
  /* The attribute selectors above are more specific than a bare `.workspace`,
     so without repeating them here the grid kept reserving a 264px column for
     a palette that is off-canvas at this width: at 375px the canvas track was
     111px and the sheet inside it overflowed the screen. Two attributes match
     whatever the values are, so this is one rule rather than eight. */
  .workspace,
  .workspace[data-palette][data-inspector] {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "canvas";
  }
  .ws-palette, .ws-inspector {
    position: fixed;
    inset-block: var(--topbar-h) 0;
    z-index: var(--z-drawer);
    inline-size: min(320px, 88vw);
    box-shadow: var(--sh-5);
    /* Same reason as the sidebar drawer: an off-canvas palette still holds
       fifty-nine focusable tiles, and without this a keyboard user tabs
       through every one of them with nothing on screen. */
    visibility: hidden;
    transition: transform var(--dur-3) var(--ease-out),
                visibility var(--dur-3) var(--ease-out);
  }
  .ws-palette { inset-inline-start: 0; transform: translateX(calc(-101% * var(--dir-flip))); }
  .ws-inspector { inset-inline-end: 0; transform: translateX(calc(101% * var(--dir-flip))); }
  .workspace[data-palette="open"] .ws-palette { transform: none; visibility: visible; }
  .workspace[data-inspector="open"] .ws-inspector { transform: none; visibility: visible; }
}

/* A pane collapsed to a zero-width column on a wide screen is invisible too,
   so its contents leave the tab order with it. */
.workspace[data-palette="hidden"] .ws-palette,
.workspace[data-palette="closed"] .ws-palette,
.workspace[data-inspector="hidden"] .ws-inspector,
.workspace[data-inspector="closed"] .ws-inspector { visibility: hidden; }

/* ==========================================================================
   Canvas objects — the blocks the user arranges
   ========================================================================== */
.canvas-sheet {
  max-inline-size: 760px;
  margin-inline: auto;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-3);
  padding: var(--s-6);
  min-block-size: 260px;
}
.canvas-sheet--wide { max-inline-size: 1100px; }

/* On a phone the panes are the whole screen, not most of it.
   A 320px sheet on a 375px viewport covers 85% and leaves a 55px strip of
   canvas, which is neither one pane nor two: you cannot read what is behind it
   and you cannot forget it is there. DESIGN.md asks the builder to degrade to
   a single-pane flow, so below this width it does — the pane is the screen,
   its header carries the way out, and Escape closes it.

   The canvas gets its padding back at the same time: at 375px the well and the
   sheet were spending 96px of 375 on their own margins. This block sits after
   the rules it overrides because both are one class deep, so order decides. */
@media (max-width: 620px) {
  .ws-palette, .ws-inspector { inline-size: 100%; box-shadow: none; }
  .ws-canvas { padding: var(--s-4) var(--s-3) var(--s-16); }
  .canvas-sheet { padding: var(--s-4); }
}

.block {
  position: relative;
  border: 1.5px solid transparent;
  border-radius: var(--r-md);
  padding: var(--s-3);
  margin-block-end: var(--s-2);
  cursor: pointer;
  transition: border-color var(--dur-1) var(--ease-out), background var(--dur-1) var(--ease-out);
}
.block:hover { border-color: var(--brand-200); background: var(--bg-subtle); }
.block.is-selected {
  border-color: var(--brand-solid);
  background: var(--brand-bg);
  box-shadow: 0 0 0 3px var(--brand-ring);
}
.block.is-dragging { opacity: 0.4; }

/* Floating handle rail — appears on hover/selection, never shifts layout. */
.block-rail {
  position: absolute;
  inset-block-start: var(--s-2);
  inset-inline-end: var(--s-2);
  display: flex;
  gap: 2px;
  padding: 2px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  box-shadow: var(--sh-2);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-1) var(--ease-out);
}
.block:hover .block-rail, .block.is-selected .block-rail, .block-rail:focus-within {
  opacity: 1;
  pointer-events: auto;
}
.block-rail button {
  display: flex; align-items: center; justify-content: center;
  inline-size: 26px; block-size: 26px;
  border-radius: var(--r-xs);
  color: var(--fg-muted);
}
.block-rail button:hover { background: var(--bg-hover); color: var(--fg-strong); }
/* A 26px hit area is a mouse size. On a finger-driven device the same rail
   has to clear the touch minimum or the builder is desktop-only, which is
   exactly what this rebuild exists to stop. */
@media (pointer: coarse) {
  .block-rail button { inline-size: var(--tap-min); block-size: var(--tap-min); }
}
.block-rail button.danger:hover { background: var(--bad-bg); color: var(--bad-fg); }
.block-rail .drag { cursor: grab; }
.block-rail svg { inline-size: 15px; block-size: 15px; }

/* Drop indicator — a single confident line, not a ghost box. */
.drop-line {
  block-size: 3px;
  border-radius: var(--r-full);
  background: var(--brand-solid);
  margin-block: var(--s-1);
  box-shadow: 0 0 0 3px var(--brand-ring);
  animation: fade-in var(--dur-1) var(--ease-out);
}
.drop-zone {
  border: 2px dashed var(--border-strong);
  border-radius: var(--r-lg);
  padding: var(--s-8) var(--s-4);
  text-align: center;
  color: var(--fg-subtle);
  font-size: var(--t-sm);
  transition: border-color var(--dur-2) var(--ease-out), background var(--dur-2) var(--ease-out);
}
.drop-zone.is-over { border-color: var(--brand-solid); background: var(--brand-bg); color: var(--brand-fg); }

/* Palette tiles — the field types you drag onto the canvas. */
.palette-group { margin-block-end: var(--s-4); }
.palette-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-2); }
.palette-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s-1);
  padding: var(--s-3) var(--s-2);
  min-block-size: 68px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  font-size: var(--t-2xs);
  font-weight: var(--fw-medium);
  color: var(--fg-muted);
  text-align: center;
  cursor: grab;
  transition: all var(--dur-2) var(--ease-out);
}
.palette-tile:hover {
  border-color: var(--brand-solid);
  background: var(--brand-bg);
  color: var(--brand-fg);
  transform: translateY(-1px);
  box-shadow: var(--sh-2);
}
.palette-tile:active { cursor: grabbing; transform: none; }
.palette-tile svg { inline-size: 19px; block-size: 19px; }

/* Inspector sections — collapsible so advanced settings stay out of the way. */
.insp-section { border-block-end: 1px solid var(--border-subtle); }
.insp-section > summary {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-1);
  font-size: var(--t-sm);
  font-weight: var(--fw-semi);
  color: var(--fg-strong);
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.insp-section > summary::-webkit-details-marker { display: none; }
.insp-section > summary::before {
  content: "";
  inline-size: 14px; block-size: 14px;
  flex: 0 0 auto;
  background: currentColor;
  color: var(--fg-subtle);
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 4l4 4-4 4'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: rotate var(--dur-2) var(--ease-out);
  rotate: calc(0deg);
}
[dir="rtl"] .insp-section > summary::before { scale: -1 1; }
.insp-section[open] > summary::before { rotate: 90deg; }
[dir="rtl"] .insp-section[open] > summary::before { rotate: -90deg; }
.insp-section > summary:hover { color: var(--brand-fg); }
.insp-body { display: flex; flex-direction: column; gap: var(--s-4); padding: var(--s-1) var(--s-1) var(--s-4); }

/* ==========================================================================
   Wizard / stepper — the guided "build me an app" flow
   ========================================================================== */
.stepper { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }
.step {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--t-sm);
  color: var(--fg-subtle);
  font-weight: var(--fw-medium);
}
.step .n {
  display: flex; align-items: center; justify-content: center;
  inline-size: 24px; block-size: 24px;
  border-radius: var(--r-full);
  border: 1.5px solid var(--border-strong);
  font-size: var(--t-xs);
  font-weight: var(--fw-semi);
  flex: 0 0 auto;
}
.step.is-current { color: var(--brand-fg); }
.step.is-current .n { border-color: var(--brand-solid); background: var(--brand-bg); color: var(--brand-fg); }
.step.is-done { color: var(--fg-muted); }
.step.is-done .n {
  border-color: var(--ok-solid);
  background: var(--ok-solid);
  color: var(--fg-onbrand);
  font-size: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5l3 3 6-6.5'/%3E%3C/svg%3E");
  background-size: 14px;
  background-position: center;
  background-repeat: no-repeat;
}
.step-sep { inline-size: 20px; block-size: 1px; background: var(--border-strong); }
@media (max-width: 620px) { .step .txt { display: none; } .step-sep { inline-size: 12px; } }

/* ==========================================================================
   Command palette — ⌘K / Ctrl-K navigation for everything
   ========================================================================== */
.cmdk-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  background: var(--overlay);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 12vh var(--s-4) var(--s-4);
}
.cmdk {
  inline-size: 100%;
  max-inline-size: 620px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-5);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  max-block-size: 62vh;
  animation: modal-in var(--dur-3) var(--ease-out);
}
.cmdk-input {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-4);
  border-block-end: 1px solid var(--border);
}
.cmdk-input svg { inline-size: 18px; block-size: 18px; color: var(--fg-subtle); flex: 0 0 auto; }
.cmdk-input input {
  flex: 1; border: none; background: none; outline: none;
  font-size: var(--t-lg); color: var(--fg-strong);
}
.cmdk-list { overflow-y: auto; padding: var(--s-2); }
.cmdk-item {
  display: flex; align-items: center; gap: var(--s-3);
  inline-size: 100%;
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-md);
  font-size: var(--t-sm);
  color: var(--fg-default);
  text-align: start;
  cursor: pointer;
}
.cmdk-item[aria-selected="true"] { background: var(--brand-bg); color: var(--brand-fg); }
.cmdk-item svg { inline-size: 16px; block-size: 16px; color: var(--fg-subtle); flex: 0 0 auto; }
.cmdk-item[aria-selected="true"] svg { color: var(--brand-fg); }
.cmdk-item .where { margin-inline-start: auto; font-size: var(--t-xs); color: var(--fg-subtle); }
