/* ==========================================================================
   MAHER SHELLS — layout for whole artifacts, keyed on <html data-format="...">.
   Tokens only, same layer as kit.css. Frames (.sheet, .slide) live in kit.css;
   this file lays them out on screen and on paper.
   ========================================================================== */

@layer utilities {
  @layer maher {

    /* --- Desk: the quiet surface behind pages and slides ------------------ */
    .desk { background-color: var(--color-base-200); min-height: 100vh; }

    /* --- Document ----------------------------------------------------------
       .sheet is the page column. Text sits in .measure; .breakout lets tables
       and figures use the full sheet width.                                 */
    [data-format="doc"] .sheet {
      max-width: 56rem;
      margin-inline: auto;
      padding: clamp(1.25rem, 5vw, 4rem);
      background-color: var(--color-base-100);
      font-size: 1.0625rem;   /* documents read a touch larger than apps */
    }
    /* A one-pager's sheet is only a wrapper for the fixed .page inside it. */
    [data-format="doc"] .sheet:has(> .page) { max-width: none; padding: 0; background-color: transparent; display: flow-root; }
    .breakout { max-width: none; width: 100%; }
    /* Cover: a full first page for proposals and long reports. */
    .cover { min-height: min(70vh, 40rem); display: flex; flex-direction: column; justify-content: flex-end; break-after: page; }
    .page-break { break-before: page; }

    /* Cover anatomy: mark and reference on top, the title, who it is for, a nickel
       hairline, then Prepared by / Date / Valid until. */
    .cover-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
    .cover > .cover-top { margin-block-end: auto; }
    .cover-title { text-box: trim-both cap alphabetic; }
    .cover-meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: 1rem 2rem; padding-block-start: 1.25rem; border-top: var(--border) solid color-mix(in oklab, var(--color-nickel) 70%, transparent); }
    .cover-meta dt { font-size: calc(var(--step--1) * var(--type-scale)); font-weight: 600; opacity: 0.8; }

    /* Numbered sections: section numbers come from a counter, so they never drift.
       Put .numbered on the article; every h2.t-title inside gets its number. */
    .numbered { counter-reset: sec; }
    .numbered h2.t-title { counter-increment: sec; }
    .numbered h2.t-title::before {
      content: counter(sec, decimal-leading-zero);
      display: block; margin-block-end: 0.35rem;
      font-family: var(--font-display); font-size: calc(var(--step-0) * var(--type-scale)); letter-spacing: 0.04em; color: var(--color-subtle);
    }
    /* Contents: a plain list of anchor links, numbered like the sections. */
    .toc ol { counter-reset: toc; display: flex; flex-direction: column; gap: 0.5rem; }
    .toc li { counter-increment: toc; display: flex; align-items: baseline; gap: 0.9rem; }
    .toc li::before { content: counter(toc, decimal-leading-zero); font-family: var(--font-display); color: var(--color-subtle); min-inline-size: 1.75rem; }
    .toc a { text-decoration: none; border-bottom: 1px solid var(--color-base-300); }
    .toc a:hover { border-color: var(--color-wood); }

    /* Margin notes: sources and definitions beside the text on wide screens, after it
       on phones and in print. Set in Fraunces italic so they read as asides. */
    .with-notes { display: grid; gap: 1.25rem 2.5rem; }
    .margin-note { font-family: var(--font-display); font-style: italic; font-size: calc(var(--step--1) * var(--type-scale)); line-height: 1.45; color: var(--color-muted);
                   border-inline-start: 2px solid var(--color-base-300); padding-inline-start: 0.9rem; max-inline-size: 24rem; }
    @media (min-width: 64rem) {
      [data-format="doc"] .with-notes { grid-template-columns: minmax(0, var(--measure)) minmax(11rem, 1fr); align-items: start; }
      [data-format="doc"] .with-notes > .margin-note { grid-column: 2; }
      [data-format="doc"] .with-notes > :not(.margin-note) { grid-column: 1; }
    }

    /* Signatures: space to sign above the line; the sender arrives signed. */
    .sign { display: flex; flex-direction: column; gap: 0.35rem; padding-block-start: 3.5rem; border-bottom: var(--border) solid var(--color-base-content); }
    .sign-signed { padding-block-start: 1rem; }
    .sign-name { font-family: var(--font-display); font-style: italic; font-variation-settings: var(--font-display-expressive); font-size: calc(var(--step-2) * var(--type-scale)); line-height: 1; }

    /* Browser frame for showing a screen inside a document (a mock-up, not a screenshot). */
    .screen-frame { border: var(--border) solid var(--color-base-300); border-radius: var(--radius-box); overflow: hidden; background-color: var(--color-base-100); }
    .screen-frame > .screen-bar { display: flex; align-items: center; gap: 0.4rem; padding: 0.5rem 0.75rem; border-bottom: var(--border) solid var(--color-base-300); background-color: var(--color-base-200); }
    .screen-frame > .screen-bar > i { inline-size: 0.55rem; block-size: 0.55rem; border-radius: 999px; background-color: var(--color-base-300); }

    /* --- Deck ---------------------------------------------------------------
       Slides stack vertically and snap, each sized to fit the viewport, so the
       same file scrolls on a phone and presents with the arrow keys.        */
    [data-format="deck"] { scroll-snap-type: y mandatory; scroll-behavior: smooth; }
    .deck { counter-reset: slide; display: flex; flex-direction: column; align-items: center; gap: 1rem; padding: 1rem; }
    .deck > .slide {
      counter-increment: slide;
      flex: none;
      width: min(100%, calc((100vh - 2rem) * 16 / 9));
      scroll-snap-align: center;
    }
    .slide-number:empty::after { content: counter(slide); }
    /* Overview (?overview in the URL, or ?overview=2 for two across): the deck as a contact sheet of slides.
       Used for thumbnails in the library; also handy for a quick look at the whole talk. */
    [data-overview] .deck { display: grid; grid-template-columns: repeat(var(--overview-cols, 3), minmax(0, 1fr)); align-items: start; align-content: start; gap: 1.25rem; padding: 1.25rem; }
    [data-overview] .deck > .slide { width: 100%; }

    /* Present mode (press P): one slide fills the screen on navy; the rest hide.
       Builds (data-step) reveal in order; earlier steps dim if the slide asks. */
    [data-present] body { overflow: hidden; }
    [data-present] .deck { position: fixed; inset: 0; z-index: 50; display: grid; place-items: center; padding: 0; background-color: var(--color-neutral); }
    [data-present] .deck > .slide { display: none; }
    [data-present] .deck > .slide[aria-current="true"] { display: block; inline-size: min(100vw, calc(100vh * 16 / 9)); border-radius: 0; border: 0; }
    [data-present] .step-hidden { visibility: hidden; }
    [data-present] .step-past { opacity: 0.38; }
    .slide .notes { display: none; }
    .slide-progress { position: absolute; inset-inline: 0; bottom: 0; block-size: 3px; background-color: var(--color-wood); clip-path: inset(0 calc(100% - var(--progress, 0) * 100%) 0 0); }
    ::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--dur-settle); animation-timing-function: var(--ease-tailored); }
    ::view-transition-group(*) { animation-duration: var(--dur-room); animation-timing-function: var(--ease-tailored); }
    /* Presenter window (press S): current slide, next slide, notes and a clock. */
    .presenter { display: grid; grid-template-columns: 3fr 2fr; grid-template-rows: auto 1fr auto; gap: 1.25rem; padding: 1.25rem; min-block-size: 100vh; background-color: var(--color-neutral); color: var(--color-neutral-content); }
    .presenter .slide { inline-size: 100%; color: var(--color-base-content); }
    .presenter-notes { grid-column: 1 / -1; overflow: auto; font-size: 1.375rem; line-height: 1.5; max-inline-size: 60ch; }
    .presenter-clock { font-family: var(--font-body); font-variant-numeric: tabular-nums; font-size: 2rem; }

    /* --- One-pager ------------------------------------------------------------
       A fixed paper page shown on a desk. shell.js scales it to fit narrow
       screens and flags overflow. data-page="letter" switches the paper size. */
    .page {
      --page-w: 210mm; --page-h: 297mm;
      width: var(--page-w); height: var(--page-h);
      padding: 16mm;
      margin: 1.5rem auto;
      overflow: hidden;
      position: relative;
      background-color: var(--color-base-100);
      box-shadow: var(--shadow-raised);
      page: onepage;
      transform-origin: top left;
    }
    [data-page="letter"] .page { --page-w: 8.5in; --page-h: 11in; page: onepage-letter; }
    /* Zones: every part of the page has a planned place; the quote zone takes the
       spare height so there is never a dead band. */
    .page-zones { display: grid; grid-template-rows: auto auto auto 1fr auto auto; gap: 1rem; }
    [data-page="letter"] .page-zones { gap: 0.75rem; padding: 14mm; }
    /* Phones: the page reflows into a readable column instead of shrinking the sheet. */
    .page.page-flow { inline-size: auto; block-size: auto; overflow: visible; margin: 0; padding: 1.5rem 1.25rem; box-shadow: none; transform: none; }
    .page.page-flow.page-zones { display: flex; flex-direction: column; }
    .page.page-flow [class*="grid-cols-"] { grid-template-columns: 1fr !important; }
    .page.page-flow [class*="col-span-"] { grid-column: auto !important; }
    .page.page-flow figure[class*="col-span"]:not(.chart) { align-items: flex-start !important; }
    .page.page-flow .photo-portrait { max-inline-size: 12rem; }
    .page.page-flow .card-body { flex-wrap: wrap; }
    .page[data-overflow]::after {
      content: "Content overflows the page. Cut text until this notice disappears.";
      position: absolute; inset-inline: 0; bottom: 0; padding: 0.5rem 1rem;
      background-color: var(--color-error); color: var(--color-error-content);
      font-size: 0.8125rem; font-weight: 600; text-align: center;
    }

    /* --- App ---------------------------------------------------------------- */
    [data-format="app"] body { --type-scale: 0.92; min-height: 100vh; display: flex; flex-direction: column; }

    /* --- Trip ---------------------------------------------------------------- */
    /* Day navigator: a tab strip. The current day carries a camel underline, the plaid's stripe. */
    .day-nav { position: sticky; top: 0; z-index: 20; display: flex; gap: 0.25rem; overflow-x: auto; padding: 0 1rem;
               background-color: var(--color-base-100); border-bottom: var(--border) solid var(--color-base-300); scrollbar-width: none; }
    .day-nav a { flex: none; padding: 0.8rem 0.75rem 0.65rem; border-bottom: 3px solid transparent; margin-bottom: calc(-1 * var(--border));
                 font-weight: 600; font-size: var(--type-floor); color: var(--color-muted); white-space: nowrap; }
    .day-nav a:hover { color: var(--color-base-content); }
    /* On a phone the strip scrolls sideways: the right edge fades to say there is more. */
    @media (max-width: 48rem) { .day-nav { -webkit-mask-image: linear-gradient(90deg, black calc(100% - 2.5rem), transparent); mask-image: linear-gradient(90deg, black calc(100% - 2.5rem), transparent); } }
    .day-nav a[aria-current="true"] { color: var(--color-base-content); border-bottom-color: var(--color-camel); }
    [data-format="trip"] section[id] { scroll-margin-top: 4rem; }
    /* Route sketch (drawn by shell.js from the day's stops). */
    .route-sketch { display: flex; flex-direction: column; gap: 0.5rem; }
    .route-map { inline-size: 100%; block-size: auto; border: var(--border) solid var(--color-base-300); border-radius: var(--radius-box); background-color: var(--color-base-200); }
    .route-line { fill: none; stroke: var(--color-camel); stroke-width: 2.5; stroke-dasharray: 6 5; stroke-linecap: round; }
    .route-stop circle { fill: var(--color-primary); }
    .route-stop text:not(.route-label) { fill: var(--color-primary-content); font: 600 calc(13px * var(--u, 1)) var(--font-body); font-variant-numeric: tabular-nums; }
    .route-home rect { fill: var(--color-neutral); }
    .route-label { fill: var(--color-base-content); font: 500 calc(15px * var(--u, 1)) var(--font-body); paint-order: stroke; stroke: var(--color-base-200); stroke-width: calc(5px * var(--u, 1)); stroke-linejoin: round; }
    /* The halo above knocks the dashed route out behind a label, as on a printed map. */
    .route-scale line { stroke: var(--color-muted); stroke-width: 2; }
    .route-scale text { fill: var(--color-muted); font: 500 calc(13px * var(--u, 1)) var(--font-body); }
    .route-north { font-weight: 700 !important; }
    /* Stop numbers on timeline rows match the sketch. */
    .stop-num { display: inline-grid; place-items: center; inline-size: 1.6rem; block-size: 1.6rem; border-radius: 999px; background-color: var(--color-primary); color: var(--color-primary-content); font: 600 0.8125rem var(--font-body); font-variant-numeric: tabular-nums; flex: none; }
    /* Travel legs between stops. */
    .list-row.leg { padding-block: 0.35rem; color: var(--color-muted); font-size: calc(var(--step--1) * var(--type-scale)); }
    .list-row.leg > :first-child { border-inline-start: 2px dashed var(--color-camel); margin-inline-start: 1.6rem; padding-inline-start: 1rem; display: flex; align-items: center; gap: 0.5rem; grid-column: 1 / -1; }
    /* Ticket: a booking card with a perforated stub. */
    .ticket-route { display: grid; grid-template-columns: auto 1fr auto; align-items: end; gap: 1rem; }
    .ticket-line { display: flex; align-items: center; gap: 0.5rem; padding-block-end: 0.9rem; color: var(--color-muted); }
    .ticket-line::before, .ticket-line::after { content: ""; flex: 1; border-top: 1.5px dashed var(--color-nickel); }
    .ticket-stub { position: relative; border-top: 2px dashed var(--color-base-300); }
    .ticket { background-color: var(--color-base-200); }
    .ticket-stub::before, .ticket-stub::after { content: ""; position: absolute; top: -11px; inline-size: 20px; block-size: 20px; border-radius: 999px; background-color: var(--_page, var(--color-base-100)); border: var(--border) solid var(--color-base-300); }
    .ticket-stub::before { left: -11px; clip-path: inset(0 0 0 50%); }
    .ticket-stub::after { right: -11px; clip-path: inset(0 50% 0 0); }
  }
}

@page onepage { size: A4; margin: 0; }
@page onepage-letter { size: letter; margin: 0; }

@media (prefers-reduced-motion: reduce) {
  [data-format="deck"] { scroll-behavior: auto; }
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}

@media print {
  .desk { background-color: transparent; min-height: 0; }
  /* Documents print on the paper itself: no tinted panel inside white margins. */
  [data-format="doc"], [data-format="doc"] body, [data-format="trip"], [data-format="trip"] body { background: transparent !important; }
  [data-format="doc"] .sheet { max-width: none; padding: 0; }
  [data-format="deck"] { scroll-snap-type: none; }
  .deck { display: block; padding: 0; gap: 0; }
  .deck > .slide { width: 13.333in; }
  .page { margin: 0 !important; box-shadow: none; transform: none !important; }
  .page[data-overflow]::after { display: none; }
  .day-nav, [data-shell-ui], .slide .notes { display: none !important; }
  .cover { min-height: 0; height: 100vh; }
  /* On paper, margin notes go back in the margin beside their paragraph (they stack on
     narrow screens), and sections sit closer, so a memo fills its pages. */
  [data-format="doc"] .with-notes { grid-template-columns: minmax(0, 1fr) 11.5rem; gap: 0.75rem 1.5rem; align-items: start; }
  [data-format="doc"] .with-notes > .margin-note { grid-column: 2; }
  [data-format="doc"] .with-notes > :not(.margin-note) { grid-column: 1; }
  [data-format="doc"] .sheet:not(:has(> .page)) { gap: 1.25rem !important; background: transparent !important; box-shadow: none !important; border: 0 !important; }
  /* A tool prints its answer first: results, then the inputs that produced them. */
  [data-format="app"] main { display: flex !important; flex-direction: column; gap: 1.5rem; }
  [data-format="app"] main > [aria-live] { order: -1; position: static !important; }
  /* Print type: 11pt text, a slightly smaller scale and a 9.5pt floor, the sizes of a good printed memo. */
  [data-format="doc"] .sheet:not(:has(> .page)) { font-size: 11pt; --type-scale: 0.9; --type-floor: 9.5pt; }
}
