/* ══════════════════════════════════════════════════════════════════════════
   AI Product Design Lab — shared prototype shell
   ══════════════════════════════════════════════════════════════════════════

   One stylesheet for all four experiments. It replaces the Minia admin theme
   the earlier prototypes wore, which spent a fifth of every frame on a sidebar
   nothing clicked and set the explanatory copy — the part that carries the
   idea — in 12px grey.

   Three rules govern everything below.

   1. The frame is 820px tall. That is the height of the iframe the case study
      embeds the prototype in, so the whole experience lays out inside it and
      advances in place. Nothing that matters lives below a fold.

   2. Text pops or it does not ship. Explanatory prose is 17px at --ink-2,
      which is a reading colour, not a whisper. 13px is the floor and it is
      reserved for tabular metadata. Nothing is set in a grey you have to lean
      toward.

   3. Colour never carries a state alone. Every status pairs a hue with an
      icon or a shape, so the meaning survives a monochrome print and a
      red/green colour deficiency.

   Prototypes are exempt from the prose dash rule (verify-portfolio.mjs line
   69), so em dashes are used here as ordinary punctuation.
   ────────────────────────────────────────────────────────────────────────── */

/* ── Reset ─────────────────────────────────────────────────────────────── */

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

html, body {
    margin: 0;
    padding: 0;
}

/* ── Tokens ────────────────────────────────────────────────────────────────
   --ink-2 is the workhorse: it carries every explanatory sentence in the
   prototypes, so it sits at roughly 7:1 on paper rather than the 3:1 the old
   .text-muted delivered. --ink-3 is metadata only and is never asked to carry
   a sentence a visitor needs to read. */

:root {
    color-scheme: light;

    --ink:      #14161a;
    --ink-2:    #464d57;
    --ink-3:    #6b727c;

    --paper:    #ffffff;
    --paper-2:  #f4f6f8;
    --paper-3:  #eaeef2;
    --line:     #d8dde3;
    --line-2:   #c2c9d2;

    /* Semantic. Each is always drawn with an icon beside it. */
    --ok:       #14724a;
    --ok-soft:  rgba(20, 114, 74, .10);
    --warn:     #9a5b00;
    --warn-soft: rgba(154, 91, 0, .12);
    --stop:     #b3261e;
    --stop-soft: rgba(179, 38, 30, .10);

    /* Per stage accent. Each prototype sets --accent from its own hue so the
       four read as one family with four moments rather than four products. */
    --accent:      #5b31d6;
    --accent-soft: rgba(91, 49, 214, .10);
    --accent-line: rgba(91, 49, 214, .32);
    --on-accent:   #ffffff;

    --shadow-1: 0 1px 2px rgba(16, 20, 28, .06), 0 2px 8px rgba(16, 20, 28, .05);
    --shadow-2: 0 8px 32px rgba(16, 20, 28, .14);

    --r-sm: 8px;
    --r:    12px;
    --r-lg: 18px;

    --sans: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

[data-theme="dark"] {
    color-scheme: dark;

    --ink:      #f2f4f7;
    --ink-2:    #b9c0ca;
    --ink-3:    #8b929d;

    --paper:    #0e1014;
    --paper-2:  #171a20;
    --paper-3:  #1f232b;
    --line:     #2b303a;
    --line-2:   #3a4049;

    --ok:       #4ac98a;
    --ok-soft:  rgba(74, 201, 138, .14);
    --warn:     #f0ac4c;
    --warn-soft: rgba(240, 172, 76, .15);
    --stop:     #ff7b72;
    --stop-soft: rgba(255, 123, 114, .14);

    --shadow-1: 0 1px 2px rgba(0, 0, 0, .4), 0 2px 10px rgba(0, 0, 0, .3);
    --shadow-2: 0 10px 38px rgba(0, 0, 0, .55);
}

/* ── Shell ─────────────────────────────────────────────────────────────────
   A three-band grid: the thread rail that shows where this moment sits in the
   day, the canvas the experiment plays out on, and the narration bar. The
   canvas is the only band that scrolls, so the rail and the narration are
   never lost and a visitor always has the sentence explaining what they are
   looking at. */

body {
    font-family: var(--sans);
    font-size: 16px;
    line-height: 1.5;
    color: var(--ink);
    background: var(--paper-2);
    -webkit-font-smoothing: antialiased;
}

.lab {
    position: relative;
    display: grid;
    grid-template-rows: auto 1fr auto;
    height: 100vh;
    min-height: 420px;
    overflow: hidden;
}

/* ── Thread rail ───────────────────────────────────────────────────────────
   The four experiments are one afternoon, not four products. The rail says so
   on every screen: the same four moments, the current one lit, the ones behind
   it marked done. It is the single strongest cue that these are progressive,
   and it costs 58px. */

.lab-rail {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 0 22px;
    height: 58px;
    background: var(--paper);
    border-bottom: 1px solid var(--line);
}

.lab-rail-brand {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-right: 4px;
    white-space: nowrap;
}

.lab-rail-brand b {
    font-size: 15px;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--ink);
}

.lab-rail-brand span {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--ink-3);
}

.lab-steps {
    display: flex;
    align-items: center;
    gap: 2px;
    margin-left: auto;
}

.lab-step {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6px 12px;
    border-radius: 999px;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--ink-3);
    text-decoration: none;
    white-space: nowrap;
}

.lab-step .n {
    display: inline-grid;
    place-items: center;
    width: 19px;
    height: 19px;
    border-radius: 50%;
    border: 1.5px solid currentColor;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
}

/* A stage already played reads as settled: filled marker, ink-2 label. */
.lab-step.is-done { color: var(--ink-2); }
.lab-step.is-done .n {
    background: var(--ink-2);
    border-color: var(--ink-2);
    color: var(--paper);
}

.lab-step.is-now {
    color: var(--accent);
    background: var(--accent-soft);
}
.lab-step.is-now .n {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--on-accent);
}

.lab-step-sep {
    color: var(--line-2);
    font-size: 12px;
}

/* ── Canvas ────────────────────────────────────────────────────────────── */

.lab-canvas {
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 20px 22px 24px;
}

.lab-wrap {
    max-width: 1120px;
    margin: 0 auto;
}

/* ── Carried in ────────────────────────────────────────────────────────────
   Stages two through four open by naming the artifact they inherited. This is
   the mechanism that makes the progression real rather than asserted: the
   thing you finished on the last screen is sitting at the top of this one. */

.lab-carried {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    padding: 12px 15px;
    margin-bottom: 18px;
    border: 1px solid var(--accent-line);
    border-left-width: 3px;
    border-radius: var(--r);
    background: var(--accent-soft);
}

.lab-carried .ico {
    flex: none;
    margin-top: 1px;
    color: var(--accent);
    font-size: 17px;
    line-height: 1;
}

.lab-carried .lb {
    display: block;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 2px;
}

.lab-carried p {
    margin: 0;
    font-size: 15px;
    line-height: 1.45;
    color: var(--ink);
}

/* ── Headline block ────────────────────────────────────────────────────── */

.lab-head { margin-bottom: 20px; }

.lab-eyebrow {
    display: block;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 7px;
}

.lab-h1 {
    margin: 0 0 8px;
    font-size: 29px;
    line-height: 1.18;
    font-weight: 700;
    letter-spacing: -.022em;
    color: var(--ink);
}

/* The sentence that makes the experiment make sense. It is 17px and it is not
   grey. This is the line the old prototypes set at 12.5px .text-muted. */
.lab-sub {
    margin: 0;
    max-width: 68ch;
    font-size: 17px;
    line-height: 1.52;
    color: var(--ink-2);
}

.lab-sub strong, .lab-sub b { color: var(--ink); font-weight: 650; }

/* ── Panels ────────────────────────────────────────────────────────────── */

.lab-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.62fr) minmax(0, 1fr);
    gap: 18px;
    align-items: start;
}

.lab-col { display: grid; gap: 18px; align-content: start; }

.lab-card {
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    background: var(--paper);
    box-shadow: var(--shadow-1);
    overflow: hidden;
}

.lab-card-hd {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 14px 18px 0;
}

.lab-card-hd h2 {
    margin: 0;
    font-size: 16.5px;
    font-weight: 680;
    letter-spacing: -.012em;
    color: var(--ink);
}

.lab-card-hd .step-n {
    display: inline-grid;
    place-items: center;
    width: 22px;
    height: 22px;
    flex: none;
    border-radius: 6px;
    background: var(--accent);
    color: var(--on-accent);
    font-size: 12px;
    font-weight: 700;
}

.lab-card-hd .spacer { margin-left: auto; }

/* Panel-level explanation. 15px, --ink-2, never smaller. */
.lab-note {
    margin: 6px 18px 0;
    font-size: 15px;
    line-height: 1.5;
    color: var(--ink-2);
}

.lab-note strong { color: var(--ink); font-weight: 650; }

.lab-card-bd { padding: 14px 18px 18px; }

.lab-card.is-muted { background: var(--paper-2); box-shadow: none; }

/* A panel not yet reachable in the flow dims rather than disappearing, so the
   shape of what is coming stays visible. */
.lab-card.is-waiting { opacity: .48; }
.lab-card.is-waiting * { pointer-events: none; }

/* ── Section label ─────────────────────────────────────────────────────── */

.lab-label {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 4px 0 10px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--ink-2);
}

.lab-label .hint {
    letter-spacing: 0;
    text-transform: none;
    font-size: 13px;
    font-weight: 500;
    color: var(--ink-3);
}

/* ── Chips ─────────────────────────────────────────────────────────────────
   13px, semibold, with a glyph. The old chips ran 11.5px and leaned on hue. */

.lab-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 9px;
    border-radius: 999px;
    border: 1px solid transparent;
    font-size: 13px;
    font-weight: 650;
    line-height: 1.35;
    white-space: nowrap;
}

.lab-chip i, .lab-chip .g { font-size: 14px; line-height: 1; }

.lab-chip.is-ok      { color: var(--ok);     background: var(--ok-soft);     border-color: var(--ok-soft); }
.lab-chip.is-warn    { color: var(--warn);   background: var(--warn-soft);   border-color: var(--warn-soft); }
.lab-chip.is-stop    { color: var(--stop);   background: var(--stop-soft);   border-color: var(--stop-soft); }
.lab-chip.is-accent  { color: var(--accent); background: var(--accent-soft); border-color: var(--accent-soft); }
.lab-chip.is-plain   { color: var(--ink-2);  background: var(--paper-3);     border-color: var(--paper-3); }

/* ── Buttons ───────────────────────────────────────────────────────────── */

.lab-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 9px 16px;
    border-radius: 10px;
    border: 1px solid var(--line-2);
    background: var(--paper);
    color: var(--ink);
    font-family: inherit;
    font-size: 14.5px;
    font-weight: 620;
    line-height: 1.2;
    cursor: pointer;
    transition: background .14s ease, border-color .14s ease, transform .08s ease;
}

.lab-btn:hover:not(:disabled) { background: var(--paper-2); border-color: var(--ink-3); }
.lab-btn:active:not(:disabled) { transform: translateY(1px); }

.lab-btn:disabled { opacity: .42; cursor: not-allowed; }

.lab-btn.is-primary {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--on-accent);
}
.lab-btn.is-primary:hover:not(:disabled) { filter: brightness(1.08); background: var(--accent); border-color: var(--accent); }

.lab-btn.is-stop {
    background: var(--stop);
    border-color: var(--stop);
    color: #fff;
}
.lab-btn.is-stop:hover:not(:disabled) { filter: brightness(1.08); background: var(--stop); }

.lab-btn.is-sm { padding: 6px 11px; font-size: 13.5px; border-radius: 8px; }

.lab-btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Segmented choice. Used wherever the person picks between named options
   rather than typing, which is most of the steering in these prototypes. */

.lab-seg { display: inline-flex; gap: 6px; flex-wrap: wrap; }

.lab-seg .lab-btn.is-on {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--on-accent);
}

/* ── Key/value read-out ────────────────────────────────────────────────────
   The live contract panel in Steer, the run summary in Oversee. Values are
   --ink and semibold: the read-out is the point of the panel, so it is the
   most legible thing in it. */

.lab-kv {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
    padding: 8px 0;
    border-bottom: 1px solid var(--line);
    font-size: 15px;
}

.lab-kv:last-child { border-bottom: 0; }
.lab-kv .k { color: var(--ink-2); }
.lab-kv .v { color: var(--ink); font-weight: 650; text-align: right; }
.lab-kv .v.is-undecided { color: var(--warn); font-weight: 650; }

/* ── Log ───────────────────────────────────────────────────────────────────
   Every prototype keeps a record, because the claim each one makes is that the
   behaviour is auditable. 13.5px mono, and the timestamp is the only thing at
   --ink-3. */

.lab-log {
    font-family: var(--mono);
    font-size: 13.5px;
    line-height: 1.75;
    max-height: 168px;
    overflow-y: auto;
    padding: 11px 13px;
    border-radius: var(--r-sm);
    border: 1px solid var(--line);
    background: var(--paper-2);
    color: var(--ink);
}

.lab-log div + div { margin-top: 2px; }
.lab-log .t { color: var(--ink-3); }
.lab-log .ok { color: var(--ok); }
.lab-log .wn { color: var(--warn); }
.lab-log .st { color: var(--stop); }

/* ── Meter ─────────────────────────────────────────────────────────────── */

.lab-meter {
    height: 9px;
    border-radius: 999px;
    background: var(--paper-3);
    overflow: hidden;
}

.lab-meter > i {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: var(--accent);
    transition: width .5s cubic-bezier(.22, .8, .3, 1), background .3s ease;
}

/* ── Stat row ──────────────────────────────────────────────────────────── */

.lab-stats {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 4px;
}

.lab-stat { text-align: center; padding: 4px 2px; }

.lab-stat .n {
    display: block;
    font-size: 26px;
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
    color: var(--ink);
}

.lab-stat .l {
    display: block;
    margin-top: 3px;
    font-size: 12px;
    font-weight: 650;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--ink-2);
}

.lab-stat.is-ok   .n { color: var(--ok); }
.lab-stat.is-warn .n { color: var(--warn); }
.lab-stat.is-stop .n { color: var(--stop); }

/* ── Narration bar ─────────────────────────────────────────────────────────
   The answer to "these are hard to follow". A sentence, 17px, in the reading
   colour, saying what just happened and why it matters, driven by the same
   timeline that drives the demo. It is present whether the demo is running or
   the visitor is driving, so there is never a moment on screen without a
   caption explaining it. */

.lab-narrate {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 13px 22px;
    background: var(--paper);
    border-top: 1px solid var(--line);
    box-shadow: 0 -2px 14px rgba(16, 20, 28, .05);
}

[data-theme="dark"] .lab-narrate { box-shadow: 0 -2px 18px rgba(0, 0, 0, .4); }

.lab-narrate-body { min-width: 0; flex: 1; }

.lab-beat {
    display: block;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 3px;
}

.lab-say {
    margin: 0;
    font-size: 17px;
    line-height: 1.42;
    font-weight: 500;
    color: var(--ink);
}

.lab-say b { font-weight: 700; }

.lab-narrate-ctl {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: none;
}

/* Progress pips: how many beats in the story, and which one is on screen. */
.lab-pips { display: flex; gap: 4px; margin-right: 4px; }

.lab-pip {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--line-2);
    transition: background .2s ease, transform .2s ease;
}

.lab-pip.is-done { background: var(--ink-3); }
.lab-pip.is-now  { background: var(--accent); transform: scale(1.35); }

/* ── Cover ─────────────────────────────────────────────────────────────────
   What a visitor meets first, and what the lab index card shows in its frame.
   It states the moment, the one sentence that is the point, and offers two
   doors: watch it, or drive it. The old prototypes offered neither and put
   their instructions in the footer. */

.lab-cover {
    position: absolute;
    inset: 0;
    z-index: 40;
    display: grid;
    place-items: center;
    padding: 28px;
    background: var(--paper);
    text-align: center;
}

/* Once dismissed the cover leaves the layer entirely. Fading it to zero
   opacity alone left a full-bleed element sitting over the canvas, which
   ghosts through during the fade and stays in the accessibility tree after. */
.lab-cover.is-gone {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .35s ease, visibility 0s linear .35s;
}

.lab-cover-in { max-width: 640px; }

.lab-cover .moment {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 5px 13px;
    margin-bottom: 18px;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .04em;
}

.lab-cover h1 {
    margin: 0 0 14px;
    font-size: 38px;
    line-height: 1.12;
    font-weight: 700;
    letter-spacing: -.03em;
    color: var(--ink);
}

.lab-cover .point {
    margin: 0 auto 26px;
    max-width: 54ch;
    font-size: 18.5px;
    line-height: 1.5;
    color: var(--ink-2);
}

.lab-cover .point strong { color: var(--ink); font-weight: 650; }

.lab-cover-doors {
    display: flex;
    gap: 10px;
    justify-content: center;
    flex-wrap: wrap;
}

.lab-cover .lab-btn { padding: 12px 22px; font-size: 15.5px; }

.lab-cover .runtime {
    margin: 16px 0 0;
    font-size: 13.5px;
    color: var(--ink-3);
}

/* ── Highlight pulse ───────────────────────────────────────────────────────
   The demo tells the eye where to look. Anything the timeline touches gets a
   ring for a beat, which is how a visitor follows an automated run without a
   cursor to track. */

@keyframes lab-pulse {
    0%   { box-shadow: 0 0 0 0 var(--accent-line); }
    60%  { box-shadow: 0 0 0 7px transparent; }
    100% { box-shadow: 0 0 0 0 transparent; }
}

.lab-focus {
    animation: lab-pulse 1.1s ease-out;
    border-radius: var(--r-sm);
}

/* Short frames. The lab index runs each prototype live inside a 16:10 card,
   which is a few hundred pixels tall, and that card shows the cover. The cover
   has to state the moment and its one sentence at that size, so it drops its
   runtime line and comes down a couple of type steps rather than centring a
   38px headline below the visible edge. */

@media (max-height: 540px) {
    .lab-cover { padding: 16px; }
    .lab-cover .moment { margin-bottom: 10px; padding: 4px 11px; font-size: 12px; }
    .lab-cover h1 { font-size: 24px; margin-bottom: 10px; }
    .lab-cover .point { font-size: 15px; line-height: 1.45; margin-bottom: 16px; }
    .lab-cover .lab-btn { padding: 8px 15px; font-size: 14px; }
    .lab-cover .runtime { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .lab-focus { animation: none; }
    .lab-meter > i { transition: none; }
    .lab-cover.is-gone { transition: none; }
}

/* ── Card mode ─────────────────────────────────────────────────────────────
   Set by lab.js from ?card=1, for the tile on the portfolio work index. The
   frame is the card's media, so the card's stretched link takes every click
   and the prototype takes none. The cover's buttons stay drawn, because they
   are half of what the tile is showing: this is a thing you can run, not a
   screenshot of one. */

html[data-lab-card="1"] .lab { pointer-events: none; }
html[data-lab-card="1"] .lab-cover .lab-btn { cursor: default; }

/* ── Utility ───────────────────────────────────────────────────────────── */

.lab-row { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.lab-row.is-tight { gap: 6px; }
.lab-spread { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.lab-stack { display: grid; gap: 11px; }
.num { font-variant-numeric: tabular-nums; }
.lab-hide { display: none !important; }

.lab-sr {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ── Narrow frames ─────────────────────────────────────────────────────────
   The case study offers a mobile toggle on the sandbox, and the lab index
   embeds the prototype in a card. Below 860px the two columns stack and the
   rail keeps only the current moment, so the shell never squeezes the content
   into a strip. */

@media (max-width: 860px) {
    .lab-grid { grid-template-columns: minmax(0, 1fr); }
    .lab-step:not(.is-now) { display: none; }
    .lab-step-sep { display: none; }
    .lab-h1 { font-size: 25px; }
    .lab-cover h1 { font-size: 30px; }
    .lab-cover .point { font-size: 17px; }
    .lab-canvas { padding: 16px 15px 20px; }
    .lab-rail { padding: 0 15px; gap: 10px; }
    .lab-narrate { padding: 11px 15px; gap: 12px; }
    .lab-say { font-size: 15.5px; }
    .lab-narrate-ctl .lab-btn span { display: none; }
}
