/* AdEQ — the layout system. SPEC-LAYOUT-V1.
 *
 * Every space, size, width, radius, and layer in the product is a token in
 * this file, and the shared layout pieces below are built from nothing else.
 * Franz, 2026-10-16 (D11): an 8px rhythm with 4px half-steps, and every new
 * page built only from the shared l- pieces and these tokens.
 *
 * WHY A FILE OF ITS OWN. app.css grew to 56 distinct paddings, 30 gaps, 22
 * breakpoints, nine button sizes, and ten chip sizes, each one a local fix to
 * a real complaint ("theres no unifrom spacing", "spacing aint proepr", "the
 * top parts are still not in horizontal alignement please do a permamnent
 * fix"). The stick tokens were the one complaint that became a token, and the
 * one that never came back. This is that move, made for everything.
 *
 * WHAT IS NOT HERE: colour. Themes redefine colour in app.css and nothing
 * else. No theme rule, no prefers-color-scheme block, and no [data-theme]
 * selector may redefine a token in this file; tools/check-layout.mjs fails a
 * file that does, and tools/check-shots.mjs fails a page whose boxes move
 * between day and night.
 *
 * LOADED FIRST, before app.css and every screen-*.css. Tokens do not care
 * about order; the pieces do, so a screen's own file can still adjust one and
 * a legacy rule keeps winning until its migration step deletes it. No @layer:
 * unlayered legacy rules would beat every layered piece. */

:root {
  /* ── SPACING: 8 IS THE RHYTHM ─────────────────────────────────────────────
     The number counts eights: --s-3 is 24. Use these between things. */
  --s-0: 0;
  --s-1: 8px;
  --s-2: 16px;
  --s-3: 24px;
  --s-4: 32px;
  --s-5: 40px;
  --s-6: 48px;
  --s-8: 64px;
  --s-12: 96px;
  /* THE HALF-STEP: inside a thing (a control, a card head, a row), never
     between two things. It announces itself in the source by its name. */
  --s-half: 4px;
  --s-1h: 12px;
  /* THE NUDGE: inside chips and tags only. */
  --s-nudge: 2px;
  /* HAIRLINE COMPENSATION only: the border a bare sticky strip does not have. */
  --s-px: 1px;

  /* ── ROLES: what screens actually use ───────────────────────────────────── */
  --gap-inline: var(--s-1);      /* icon and word, chip and chip, inside one group */
  --gap-toolbar: var(--s-2);     /* groups in a toolbar */
  --gap-label: var(--s-1);       /* a label and its control */
  --gap-field: var(--s-3);       /* one field and the next. D11: 24 */
  --gap-card: var(--s-2);        /* card and card */
  --gap-section: var(--s-4);     /* section and section on a page */
  /* THE BODY AND ITS RIGHT COLUMN (Franz, 2026-11-03: "a big gap between the
     body section stuff and the right column ... make it even with the tool
     bar up and down spacing"): 20, the toolbar's own. What the old gap gave
     back goes half to the body and half to the column (each layout adds
     (old gap − this) ÷ 2 to its column; the body's 1fr takes the rest). */
  --gap-rail: calc(var(--s-2) + var(--s-half));
  --pad-card: var(--s-2);        /* inside a card, four equal sides */
  --pad-modal: var(--s-3);       /* inside a modal or drawer */
  --pad-row-x: var(--s-1h);      /* a row's sides; height is --h-row */
  --pad-control-x: var(--s-1h);  /* a button's or input's sides; height is --h-* */
  --pad-chip-x: var(--s-1h);     /* a chip's sides; height is --h-sm */

  /* design-convention's density knobs, so a kit export speaks the same names */
  --ch: var(--h-md);
  --cp: var(--pad-card);
  --gp: var(--gap-card);

  /* ── HEIGHTS ──────────────────────────────────────────────────────────────
     Height is a token and padding sets the sides only, so two controls in one
     row agree whatever their font. A 12.5px label beside a 13px one used to
     make two buttons a pixel apart; that is what "not aligned" usually was. */
  --h-xs: 24px;
  --h-sm: 28px;
  --h-md: 32px;
  --h-lg: 40px;
  --h-row: 40px;
  --h-row-dense: 32px;
  /* Off the grid on purpose: approved, and every sticky offset derives from it.
     --app-h IS THE APP HEADER ITSELF; --header-h is where a sticky thing comes
     to rest, which is the app header everywhere except under a page's pinned
     head (app.css .client-top), where it is the app bar and that block. */
  --app-h: 52px;
  --header-h: var(--app-h);

  /* ── WHERE A STICKY THING COMES TO REST, AND HOW FAR IN IT IS PADDED ───────
     Franz, 2026-09-16: "the top parts are still not in horizontal alignement
     please do a permamnent fix".

     They were not, and they never would have stayed aligned, because there was
     nothing making them agree: the scene toolbar and the Activity panel each
     carried their own copy of `calc(var(--header-h) + 16px)` and their own
     padding, and the report page's sidebar carried a hardcoded 76px that was
     the same idea written a third way. Three numbers meaning one thing is three
     places to change and two places to forget.

     THE PANEL IS THE REFERENCE, because it is the one with a visible edge: the
     eye lines everything up against the border of the Activity card. So a
     sticky panel rests at --stick-top and pads its contents by --stick-pad, and
     anything sticky WITHOUT a border adds the 1px of border it does not have,
     so the first thing inside each of them starts on the same line.

     Change these two and every sticky thing in the product moves together. */
  --stick-top: calc(var(--header-h) + var(--s-2));
  --stick-pad: var(--s-1h);
  /* A bare sticky strip has no border to account for; a card has 1px. */
  --stick-pad-bare: calc(var(--stick-pad) + var(--s-px));

  /* ── WIDTHS ───────────────────────────────────────────────────────────────
     A block never invents a max-width (SPEC-UI §4). It is one of these, or a
     grid column.

     Franz, 2026-09-14: use more of the page — the activity column was too
     narrow to read a diff in. The reading measure is unchanged: prose still
     stops at --w-read, and it is the log and the scene cards that take the
     extra width. */
  /* FULL WIDTH. Franz, 2026-10-16: "use full width of page for the whole app
     instead of shortened width ... profile and settings and work and
     everywhere". The team app's page no longer stops at 1460: the gutters
     (--pad-page) are its only edge, and boards add columns rather than
     stretching. Prose still stops at --w-read inside its card. The portal and
     the website keep their own widths (--w-site). */
  --w-page: none;
  --w-site: 1460px;
  --w-read: 74ch;
  --w-modal: 900px;
  --w-modal-sm: 560px;
  --w-drawer: 640px;
  --w-pop: 320px;
  --w-gate: 384px;
  --w-col: 320px;

  /* ── PAGE GUTTERS: 16 on a phone, 24 on a tablet, 32 on a desktop ──────── */
  --pad-page: var(--s-4);
  --pad-page-top: var(--s-2);
  /* THE PAGE ENDS THE WAY THE TOOLBAR SITS (Franz, 2026-11-04): the last thing on a page, body or right column,
     stops this far above the page's end, the same 20px the toolbar keeps above and below its controls. */
  --pad-page-end: calc(var(--s-2) + var(--s-half));

  /* ── RADIUS ───────────────────────────────────────────────────────────────
     BRAND.md's scale, unchanged, and exempt from the 8px rhythm. Nothing is a
     hard square: sm for chips and thumbnails, md for inputs, buttons, and
     cards, lg for sheets. */
  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;
  --r-pill: 999px;

  /* ── LAYERS ───────────────────────────────────────────────────────────────
     The header is on top of everything in the page (SPEC-UI §6); anything
     else that sticks sits below it. Raw 1–4 are allowed inside one component. */
  --z-local: 1;
  --z-sticky: 8;
  --z-sticky-panel: 9;
  --z-header: 10;
  --z-pop: 30;
  --z-float: 40;
  --z-sheet: 50;
  --z-modal: 60;
  --z-toast: 90;
}

/* Below desktop the app header is two rows (app.css explains why), and its
   height is the token every sticky thing rests under. */
@media (max-width: 1023px) {
  :root { --app-h: calc(52px + var(--h-lg) + var(--s-1)); --header-h: var(--app-h); --pad-page: var(--s-3); }
}
@media (max-width: 639px) {
  :root { --pad-page: var(--s-2); }
}

/* A wide screen gets a wider gutter, so full width never runs to the glass. */
@media (min-width: 1440px) {
  :root { --pad-page: var(--s-6); }
}

/* ── BREAKPOINTS ──────────────────────────────────────────────────────────────
   Four, and no others (SPEC-LAYOUT-V1 §3). A media query cannot read a
   variable, so the numbers are written out and the check enforces them:
     phone        (max-width: 639px)
     tablet up    (min-width: 640px)
     desktop up   (min-width: 1024px)   or (max-width: 1023px)
     wide         (min-width: 1440px)   or (max-width: 1439px)
     very wide    (min-width: 1920px)   or (max-width: 1919px)   (D: full width)
     tight phone  (max-width: 419px)    last resort only */

/* ═══ THE SHARED PIECES ═════════════════════════════════════════════════════
   Each piece owns its spacing. A screen composes pieces and sets grid
   columns; it never sets a margin, padding, or gap a piece already owns.
   Names follow design-convention's element ids where one exists. Nothing on
   any screen uses these yet; screens move onto them in SPEC-LAYOUT-V1 §7. */

/* ── Page ─────────────────────────────────────────────────────────────────── */
.l-page {
  max-width: var(--w-page); margin: 0 auto;
  padding: var(--pad-page-top) var(--pad-page) var(--pad-page-end);
  display: flex; flex-direction: column; gap: var(--gap-section);
}
/* Inside `main`, main already ends the page. */
main .l-page { padding-bottom: 0; }
.l-page > * { min-width: 0; }

/* ── Page head: title, quiet meta, actions pushed right, chevron last ─────── */
.l-head {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--s-1) var(--gap-toolbar); margin: 0 0 var(--s-2);
}
.l-page > .l-head { margin-bottom: calc(var(--s-2) - var(--gap-section)); }
.l-head > h1, .l-head > .l-title { font: var(--t-title); letter-spacing: var(--tr-title); margin: 0; }
.l-head > h2 { font: var(--t-section); letter-spacing: var(--tr-section); margin: 0; }
.l-head-meta { color: var(--mute); font-size: 13px; }
.l-head-acts { margin-left: auto; display: flex; align-items: center; flex-wrap: wrap; gap: var(--gap-inline); }

/* ── Toolbar: groups 16 apart, 8 inside a group, every control --h-md ─────── */
.l-bar { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-1) var(--gap-toolbar); }
.l-group { display: flex; align-items: center; flex-wrap: wrap; gap: var(--gap-inline); }
.l-bar > .is-end, .l-bar > .l-group.is-end { margin-left: auto; }
.l-bar.is-sticky {
  position: sticky; top: var(--stick-top); z-index: var(--z-sticky);
  padding: var(--stick-pad-bare) 0; background: var(--paper);
}

/* ── Card ─────────────────────────────────────────────────────────────────── */
.l-card {
  background: var(--card); border: 1px solid var(--rule-faint); border-radius: var(--r-md);
  padding: var(--pad-card); min-width: 0;
  display: flex; flex-direction: column; gap: var(--gap-field);
}
.l-card-head {
  display: flex; align-items: center; gap: var(--gap-inline); min-height: var(--h-md);
  margin-bottom: calc(var(--s-1) - var(--gap-field));
}
.l-card-head > .l-title, .l-card-head > h3 {
  font: var(--t-label); letter-spacing: var(--tr-label); color: var(--ink); margin: 0;
  min-width: 0; overflow-wrap: anywhere;
}
.l-card-head > .l-acts { margin-left: auto; display: flex; align-items: center; gap: var(--s-half); flex: none; }

/* A grid of cards. Never on a cardBoard() grid: those pack with
   grid-auto-rows: 1px, where a row-gap is counted once per pixel. */
.l-cards {
  display: grid; gap: var(--gap-card);
  grid-template-columns: repeat(auto-fill, minmax(min(var(--card-min, 280px), 100%), 1fr));
}

/* ── Panel: a card that sticks, lined up with every other sticky thing ───── */
.l-panel {
  position: sticky; top: var(--stick-top); z-index: var(--z-sticky-panel);
  padding: var(--stick-pad);
}

/* ── List rows: no box, a hairline between, one height for every list ────── */
.l-rows { display: flex; flex-direction: column; }
.l-row {
  display: flex; align-items: center; gap: var(--gap-inline);
  min-height: var(--h-row); padding: 0 var(--pad-row-x);
  border-top: 1px solid var(--rule-faint);
}
.l-rows > .l-row:first-child { border-top: 0; }
.l-row > .is-end { margin-left: auto; }
.l-rows.is-dense > .l-row { min-height: var(--h-row-dense); }

/* ── Form field: label, 8, control; fields 24 apart (D11) ─────────────────── */
.l-field { display: flex; flex-direction: column; gap: var(--gap-label); min-width: 0; }
.l-field + .l-field { margin-top: var(--gap-field); }
.l-card > .l-field + .l-field { margin-top: 0; }    /* the card's own gap already spaces them */
.l-label { font: var(--t-label); letter-spacing: var(--tr-label); color: var(--label-ink, var(--ink-soft)); }
.l-fields-2 { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--gap-field) var(--s-3); }
.l-fields-2 > .l-field + .l-field { margin-top: 0; }
@media (min-width: 640px) {
  .l-fields-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── Modal (the centred overlay; design-convention's "sheet" is the iOS
      bottom sheet, so this is not called one) ─────────────────────────────── */
.l-modal {
  position: fixed; inset: 0; z-index: var(--z-sheet);
  display: flex; justify-content: center; align-items: flex-start;
}
.l-modal-scrim { position: absolute; inset: 0; background: rgb(0 0 0 / .55); }
.l-modal-card {
  position: relative; width: 100%; max-width: var(--w-modal);
  margin: var(--s-5) var(--s-2); max-height: calc(100dvh - 2 * var(--s-5)); overflow: auto;
  background: var(--paper); border: 1px solid var(--rule); border-radius: var(--r-lg);
  padding: var(--pad-modal);
}
.l-modal.is-sm .l-modal-card { max-width: var(--w-modal-sm); }

/* ── Drawer: the right-hand panel under the header ───────────────────────── */
.l-drawer {
  position: fixed; top: var(--header-h); right: 0; bottom: 0; z-index: var(--z-float);
  width: min(var(--w-drawer), 100vw); overflow: auto;
  background: var(--paper); border-left: 1px solid var(--rule);
  padding: 0 var(--pad-modal) var(--pad-modal);
}
.l-drawer > .l-head {
  position: sticky; top: 0; z-index: var(--z-local); background: var(--paper);
  margin: 0 0 var(--s-2); padding: var(--s-2) 0;
}

/* ── Popover and menu ─────────────────────────────────────────────────────── */
.l-pop, .l-menu {
  width: var(--w-pop); max-width: calc(100vw - 2 * var(--s-2));
  padding: var(--s-1); z-index: var(--z-pop);
  background: var(--card); border: 1px solid var(--rule); border-radius: var(--r-md);
}
.l-modal .l-pop, .l-modal .l-menu, .l-drawer .l-pop, .l-drawer .l-menu { z-index: var(--z-modal); }
.l-menu { display: flex; flex-direction: column; }
.l-menu > * {
  display: flex; align-items: center; gap: var(--gap-inline);
  min-height: var(--h-md); padding: 0 var(--s-1h); border-radius: var(--r-sm);
}

/* ── Board: columns side by side, cards stacked inside ───────────────────── */
.l-kanban {
  display: flex; gap: var(--gap-card); align-items: flex-start;
  overflow-x: auto; scroll-snap-type: x proximity; padding-bottom: var(--s-1);
}
.l-col {
  flex: 0 0 var(--w-col); scroll-snap-align: start; min-width: 0;
  display: flex; flex-direction: column; gap: var(--s-1);
  padding: var(--s-1h); border-radius: var(--r-md); background: var(--shade);
}
.l-col-head { display: flex; align-items: center; gap: var(--gap-inline); min-height: var(--h-md); }

/* ── Empty state: what a thing IS, one action (SPEC-UI §10) ──────────────── */
.l-empty { padding: var(--s-5) 0; display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-1); color: var(--mute); }
.l-empty > strong { color: var(--ink); font-weight: 600; }

/* ── Toast: one place, one layer ──────────────────────────────────────────── */
.l-toast {
  position: fixed; left: var(--s-2); bottom: var(--s-2); z-index: var(--z-toast);
  padding: var(--s-1) var(--s-2); border-radius: var(--r-md);
  background: var(--ink); color: var(--paper);
}

/* ── Insert row: the pill between two cards, centred both ways ───────────────
   Franz, 2026-10-03: "i need it centre always". The offset is PADDING, never
   margin: a card's bottom margin collapses into a smaller top margin. */
.l-insert {
  display: flex; justify-content: center; align-items: center;
  padding: var(--s-1) 0; margin: 0;
}
