/* ============================================================================
   FLLOWLY — THE APPROVED SHELL, HOME AND STORIES CATALOGUE
   ----------------------------------------------------------------------------
   PHASE 1 + 2 of the approved mockup redesign. Loaded last, so it wins over
   the v2 editorial system and the v3 product surface for the surfaces it
   actually claims — and claims nothing else. The Story Reader, the Table, the
   account and the settings screens are untouched here and keep rendering
   through product.css until their own phase.

   WHAT CHANGED, AND WHY IT IS A LAYOUT CHANGE RATHER THAN A RESKIN.
   The destinations moved from a top bar to a column. A top bar has to fit its
   items into one line beside a logo, an account control and the page's own
   actions, which is why the old shell carried three destinations while the
   product has six places a person goes. A column has room, so the shell stops
   competing with the page.

   TOKENS, NOT LITERALS, AND NO FALLBACK LITERALS EITHER. Every colour here
   resolves through tokens.css so the dark palette keeps working and a future
   theme change stays one file. `var(--name, #literal)` is NOT a token use:
   when --name does not exist the literal is what ships, silently and in both
   themes. The approved lavender and the focus ring are therefore declared in
   tokens.css, once per palette, next to the surfaces they sit on. The only
   new token family declared HERE is the display serif the headings use,
   because it is a layout fact about this shell rather than a palette.
   ============================================================================ */

:root {
  /* The approved headings are a serif; the interface stays Plus Jakarta Sans.
     Georgia is the fallback that exists on every platform we support, so a
     blocked webfont degrades to a serif rather than to the UI face. */
  --font-display: "Source Serif 4", "Iowan Old Style", Georgia, "Times New Roman", serif;

  --shell-nav: 248px;
  --shell-gut: clamp(16px, 4vw, 56px);
  --shell-max: 1180px;
  --shell-r: 18px;

  /* WHAT A STICKY ELEMENT HAS TO CLEAR, NOW THAT NOTHING FLOATS OVER IT.
     The v3 top bar was fixed over the page, so every sticky panel in the
     product reserved 96–116px for it. `.topbar.is-shelled` scrolls away with
     the content, so that reservation is now a gap under nothing. One token,
     because three stylesheets made the same assumption separately. */
  --shell-stick: 20px;
}

/* ── THE SHELL ───────────────────────────────────────────────────────────── */

.shell {
  display: grid;
  grid-template-columns: var(--shell-nav) minmax(0, 1fr);
  min-height: 100dvh;
  align-items: start;
}

/* BELOW THE BREAKPOINT THE COLUMN IS NOT NARROWED, IT IS REPLACED. A 248px
   rail squeezed onto a 375px phone leaves 127px for the product. BottomNav
   takes the job instead, which is why this is `display:none` and not a width
   change. */
@media (max-width: 900px) {
  .shell { grid-template-columns: minmax(0, 1fr); }
}

.shell-main {
  min-width: 0;
  padding: 0 var(--shell-gut) 96px;
}

/* The phone's bar is fixed, so the last thing on every page would otherwise
   sit underneath it. */
@media (max-width: 900px) {
  .shell-main { padding-bottom: calc(84px + env(safe-area-inset-bottom, 0px)); }
}

/* ── SIDE NAVIGATION ─────────────────────────────────────────────────────── */

.sidenav {
  position: sticky;
  top: 0;
  align-self: start;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 28px 16px 24px;
  border-right: 1px solid var(--line);
  background: var(--void);
}

.sidenav-mark {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 28px 8px;
  padding: 4px;
  background: none;
  border: 0;
  cursor: pointer;
  border-radius: 10px;
}

.sidenav-word {
  font-family: var(--font-display);
  font-size: 23px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
}

/* ORDER MATTERS HERE, AND GETTING IT WRONG IS INVISIBLE ON A DESKTOP.
   This used to sit above `.sidenav { display: flex }`. Both rules have the
   same specificity, so the later one won and the rail rendered on a phone as
   a full-width list that pushed the page off the bottom of the screen — while
   every desktop width looked correct. It is declared after the rail now, so
   the replacement actually replaces. */
@media (max-width: 900px) {
  .sidenav { display: none; }
}

.sidenav-l { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.sidenav-l.is-foot { margin-top: auto; }

.sidenav-b {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  /* 44px minimum, which is the comfortable target size the quality audit
     settled on for every other control in this product. */
  min-height: 44px;
  padding: 10px 12px;
  border: 0;
  border-radius: 11px;
  background: none;
  color: var(--ink-2);
  font: inherit;
  font-size: var(--t-sm);
  font-weight: 500;
  text-align: left;
  cursor: pointer;
}

.sidenav-b:hover { background: var(--wash-2); color: var(--ink); }

/* THE ACTIVE STATE IS NEVER COLOUR ALONE. A filled surface, heavier ink and
   `aria-current` on the element itself — so it survives a reader who cannot
   distinguish the tint, and it is announced rather than merely seen. */
.sidenav-b.is-on {
  background: var(--lav-2);
  color: var(--primary);
  font-weight: 700;
}

.sidenav-i { flex: 0 0 auto; }
.sidenav-t { min-width: 0; }

/* ── SHARED PAGE FURNITURE ───────────────────────────────────────────────── */

.pg { max-width: var(--shell-max); margin: 0 auto; padding-top: 40px; }

.pg-h1 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(32px, 4.4vw, 46px);
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 0 0 10px;
}

.pg-sub {
  font-size: var(--t-body);
  color: var(--ink-2);
  margin: 0 0 28px;
  max-width: 62ch;
}

.pg-sec-h {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(22px, 2.6vw, 28px);
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0;
}

.pg-sec-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin: 40px 0 18px;
}

/* ── HOME: NO RULES HERE ────────────────────────────────────────────────
   A `.hm-*` block used to sit here — a decision panel, a field, chips and an
   illustration, about ninety lines of it. NOT ONE SELECTOR MATCHED ANYTHING.
   The approved Home is `screens/Landing.js`, which renders `home3-*` and is
   styled by product.css; the panel these rules described was never written.

   Dead CSS is not free. It cost nothing at runtime and quite a lot to read:
   anybody opening this file would reasonably conclude the shell owns the
   Home hero, and would change these rules expecting the page to move.
   ──────────────────────────────────────────────────────────────────────── */

/* ── STORY CARDS ─────────────────────────────────────────────────────────
   The catalogue's own markup is reused rather than replaced. `Stories.js`
   already decides what a card may say — permitted identity, the road, the
   approved title, the publication's own one-line summary, the record's own
   resolution of when, and the Ask note only where somebody agreed to be asked
   — and every one of those decisions is covered by tests. Restyling the
   classes it already emits keeps all of that and changes only the shape. */

/* THE CATALOGUE RUNS TO THE SHELL'S MEASURE, like every other screen.
   quality.css used to cap it at 760px — a column from before the shell
   existed. That rule is gone; this is the one that replaces it. */
.stories { max-width: var(--shell-max); margin: 0 auto; }

.stories-list {
  display: grid;
  gap: 16px;
  /* `min()` IS LOAD-BEARING. A bare `minmax(320px, 1fr)` sets a floor of
     320px per column, so on a 320px phone — once the page's own gutters are
     taken — the single column is wider than the viewport and the whole page
     scrolls sideways. `min(320px, 100%)` lets the column shrink to whatever
     space actually exists and keeps the two-column behaviour everywhere
     there is room for it. */
  grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
  margin-top: 26px;
}

.story-card {
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 22px;
  border-radius: var(--shell-r);
  border: 1px solid var(--line);
  background: var(--lift);
  min-width: 0;
}

/* THE IDENTITY BLOCK: mark, name, road. One row, and the road sits under the
   name rather than under the whole card, so the three read as one reference
   to a person instead of three separate facts. */
.story-card-top { display: flex; align-items: flex-start; gap: 11px; }

/* NOT A FACE. The Table's own mark, imported rather than redrawn — see
   `IdentityMark`. Only the size differs: a card is smaller than a seat. */
.story-card-face.tb3-av {
  width: 38px; height: 38px;
  font-size: 16px;
}

.story-card-id { min-width: 0; display: grid; gap: 2px; padding-top: 2px; }
.story-card-who { font-weight: 600; font-size: var(--t-sm); color: var(--ink); }

.story-card-kind {
  font-size: var(--t-xs);
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--lav-2);
  color: var(--primary);
}

.story-card-road {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  font-size: var(--t-xs); color: var(--ink-2); margin: 0;
}
.story-card-arrow { font-style: normal; opacity: .6; }

/* THE APPROVED TITLE WRAPS AND IS NEVER CLIPPED. A truncated title is the
   product editing somebody's words to fit a box. */
.story-card-t {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--t-md);
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 2px 0 0;
  overflow-wrap: anywhere;
}

.story-card-sum { font-size: var(--t-sm); line-height: 1.55; color: var(--ink-2); margin: 0; }
.story-card-when { font-size: var(--t-xs); color: var(--ink-2); margin: 0; }
.story-card-when.is-absent { font-style: italic; opacity: .85; }

/* THE CATEGORY ENDS THE CARD, and it pushes the action to the far side so the
   row reads "this is what it is about" / "read it" rather than two chips. */
.story-card-do {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-top: auto; padding-top: 14px;
}
.story-card-do .story-card-kind { margin-inline-end: auto; }

.story-card-ask { font-size: var(--t-xs); color: var(--ok, var(--primary)); }

/* ── CATALOGUE: THE SEARCH FIELD ─────────────────────────────────────────
   `cat-search` and `cat-clear` are what `screens/Stories.js` actually
   renders. The filter pills beside them are `stories-tab`, styled in
   product.css — so the `.cat-f`, `.cat-filters`, `.cat-tools` and
   `.cat-counts` rules that used to be here matched nothing and were removed
   with the Home block above. The counts are `.stories-filtered`.
   ──────────────────────────────────────────────────────────────────────── */

.cat-search {
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: 520px;
  padding: 10px 16px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--lift);
}
.cat-search input { width: 100%; border: 0; background: none; font: inherit; font-size: var(--t-body); color: var(--ink); }
.cat-search input:focus { outline: none; }
.cat-search:focus-within { border-color: var(--primary); box-shadow: 0 0 0 3px var(--ring); }

.cat-clear {
  background: none; border: 0; padding: 4px 2px;
  color: var(--primary); font: inherit; font-size: var(--t-sm);
  text-decoration: underline; cursor: pointer;
}

/* The catalogue's three empty states are `.stories-empty*` in product.css.
   A `.cat-empty` block here matched nothing and went with the rest.
   ──────────────────────────────────────────────────────────────────────── */

/* ── MOTION ──────────────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .sc, .sidenav-b { transition: none !important; }
}

/* ── THE TOP BAR, NOW THAT THE DESTINATIONS LEFT IT ──────────────────────
   It sits inside the shell's content column rather than across the window, so
   it carries the mark, the language control, the account control and the one
   action — and nothing that the side column already lists. `is-shelled` is
   what tells product.css's older rules that this bar is no longer the whole
   navigation. */

/* IT HAS TO BE UN-FIXED, NOT JUST RESTYLED. app.css sets the bar
   `position: fixed; inset: 0 0 auto 0; height: 64px; pointer-events: none`,
   which is right for a bar floating over a full-width page and wrong for one
   that lives inside a column. Restyling it without releasing the position
   left a 337px bar pinned to the viewport above a 320px column: it drew over
   the content, it set the page's scroll width, and every sticky panel in the
   product was still reserving room for it. Position, inset, height, z-index
   and pointer-events are all part of "it is in the flow now", so all five are
   restated here rather than three of them. */
.topbar.is-shelled {
  position: static;
  inset: auto;
  z-index: auto;
  height: auto;
  pointer-events: auto;

  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  width: 100%;
  max-width: var(--shell-max);
  margin: 0 auto;
  padding: 18px 0 6px;
  background: none;
  border: 0;
  box-shadow: none;
}

/* The hairline app.css draws under the floating bar belonged to a bar with a
   page behind it. In the column it is a rule across the content, so it goes. */
.topbar.is-shelled::after { content: none; }

/* `is-floating` is applied on scroll for the fixed bar's blur. A bar in the
   flow has nothing to float over. */
.topbar.is-shelled.is-floating { backdrop-filter: none; background: none; }

/* On desktop the column already carries the wordmark, so the bar's own mark
   would be the second one on screen. The phone has no column, so it keeps it. */
@media (min-width: 901px) {
  .topbar.is-shelled .mark { display: none; }
}

.topbar.is-shelled .utilities { margin-left: auto; }

/* ── THE BAR AT PHONE WIDTH ──────────────────────────────────────────────
   WHY THIS IS NEEDED AT ALL. `.utilities` is a nowrap flex row carrying the
   language control, the account control and the one action; it measures about
   250px. The mark returns below 901px because there is no side column to
   carry it. 34 + 16 + 250 is 300, and a 320px phone leaves 288 inside the
   column's gutter — so the bar grew past its own column and took the page's
   scroll width with it.

   THE BAR WRAPS INSTEAD OF SHRINKING. Squeezing the controls would make the
   account target smaller than 44px, which is the one measurement on this bar
   that is not free to move. `max-width: 100%` is the belt: whatever a future
   control does to the row, the bar cannot be wider than the column holding
   it. */
.topbar.is-shelled { max-width: min(var(--shell-max), 100%); }


@media (max-width: 900px) {
  .topbar.is-shelled { flex-wrap: wrap; row-gap: 10px; }
  .topbar.is-shelled .utilities {
    min-width: 0;
    flex-wrap: wrap;
    justify-content: flex-end;
    row-gap: 8px;
  }
}

/* ── HOME: THE LIBRARY WINDOW ────────────────────────────────────────────
   The approved Home ends with real accounts rather than a number about them.
   It reuses `.stories-list` so the grid behaves identically on both screens —
   one rule, two pages, and no chance of them drifting apart. */

.home3-lib {
  max-width: var(--shell-max);
  margin: 0 auto;
  padding: 8px 0 24px;
}

.home3-lib .pg-sec-top { margin-top: 0; }
.home3-lib .stories-list { margin-top: 4px; }

/* ── KEYBOARD FOCUS IN THE RAIL ──────────────────────────────────────────
   Declared explicitly rather than inherited, because the rail is a new
   stacking context and a ring that is drawn but clipped is a ring nobody can
   see. `:focus-visible` so a mouse press does not leave it behind. */
.sidenav-b:focus-visible,
.sidenav-mark:focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: 2px;
  border-radius: 11px;
}

/* ════════════════════════════════════════════════════════════════════════
   PHASE 4 — THE STORY READER
   ------------------------------------------------------------------------
   One reader, every story. Nothing here is per-person: the same rules draw an
   anonymous interview and a named approved publication, and the differences
   between them come from the record rather than from a branch in a stylesheet.
   ════════════════════════════════════════════════════════════════════════ */

.st3-head-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
}

/* THE APPROVAL READS AS A STATEMENT, NOT AS A SCORE. A quiet filled pill with
   a tick — no stars, no percentage, no rank. It appears only where an author
   approved the published text, and nothing is drawn in its place when they
   did not. */
.st3-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 13px;
  border-radius: 999px;
  background: var(--ok-dim);
  color: var(--ok);
  font-size: var(--t-xs);
  font-weight: 600;
  line-height: 1.2;
}

.st3-title {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.12;
  overflow-wrap: anywhere;
}

.st3-who { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* THERE IS NO MARK BESIDE THE BYLINE, so there is nothing here to style. The
   approved mockup draws one; the reader does not build one. See the note in
   Experience.js for which assertions that answers to. */

/* product.css already lays this strip out. The only change is a tighter gap,
   because the row gained a third and fourth control. */
.st3-actions { gap: 10px; }

/* ── THE TAB STRIP GAINS A SECOND LINE ───────────────────────────────────
   The approved reader glosses each phase under its label. The strip is a
   four-column grid, so the two lines stack inside the button and the label
   keeps its own line to itself.

   NOWRAP IS LIFTED FOR THE GLOSS ONLY. product.css holds the whole tab on one
   line, which is right for "Decyzja" and impossible for "Co brała pod uwagę". */
.tabs3-tab.has-sub {
  display: grid;
  gap: 2px;
  align-content: center;
  padding-top: 8px; padding-bottom: 8px;
  line-height: 1.2;
}
.tabs3-tab.has-sub .tabs3-l { font-size: var(--t-sm); }
.tabs3-tab.has-sub .tabs3-s {
  white-space: normal;
  font-size: var(--t-tag);
  font-weight: 500;
  letter-spacing: 0;
  color: var(--ink-3);
  text-transform: none;
}
/* On the selected tab the gloss follows the label into full ink, or it reads
   as disabled text sitting inside the active pill. */
.tabs3-tab.has-sub.is-on .tabs3-s { color: var(--ink-2); }

/* BELOW THE BREAKPOINT THE GLOSS IS DROPPED, NOT SHRUNK. Four two-line tabs
   inside a 320px strip give each one about 70px; the gloss would wrap to three
   lines and push the labels apart. The labels alone already name the phases,
   and the panel repeats the gloss as its own heading. */
@media (max-width: 720px) {
  .tabs3-tab.has-sub { display: block; }
  .tabs3-tab.has-sub .tabs3-s { display: none; }
}

/* The gloss again, at the top of the open panel. Quiet, because the heading
   work is done by the tab; this is a caption. */
.st3-phase-s {
  margin: 0 0 clamp(14px, 1.8vw, 22px);
  font-size: var(--t-sm);
  color: var(--ink-3);
  letter-spacing: .01em;
}

/* The saved state is carried by the label AND by the surface AND by
   `aria-pressed`, so it survives a reader who cannot tell the two fills
   apart. */
.st3-save.is-on {
  background: var(--ok);
  border-color: var(--ok);
}

/* ════════════════════════════════════════════════════════════════════════
   PHASE 3 — THE EXPERIENCE TABLE
   ------------------------------------------------------------------------
   A private workspace around one decision. Everything on it is either the
   reader's own or a grounded match; nothing is a recommendation.
   ════════════════════════════════════════════════════════════════════════ */

.tb3-topline {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}

/* IT SAYS PRIVATE BECAUSE IT IS. The Table lives in this browser's own
   storage and is sent nowhere — there is no server to send it to. */
.tb3-private {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--lav-2);
  color: var(--primary);
  font-size: var(--t-xs);
  font-weight: 600;
}

.tb3-edit {
  background: none; border: 0;
  color: var(--primary); font: inherit; font-size: var(--t-sm);
  text-decoration: underline; cursor: pointer;

  /* 44px OF TARGET, 22px OF INK. The control measured 29.7px tall, which is
     under the minimum for a finger — and it only ever appears once a Table
     exists, which is why earlier sweeps over an empty document never saw it.
     The hit area comes from the padding and the negative margin takes the
     same amount back out of the layout, so the row around it is unchanged:
     the link does not become a slab, it just becomes reachable. */
  display: inline-flex; align-items: center;
  min-height: 44px;
  padding: 4px 2px;
  margin-block: -11px;
}

.tb3-banner {
  border-radius: 16px;
  background: var(--lav-1);
  border: 1px solid var(--line);
  padding: 18px 22px;
  margin: 18px 0 20px;
}
.tb3-banner-t {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--t-lg);
  color: var(--ink);
  margin: 0;
}

/* ── THE READER'S OWN NOTE ───────────────────────────────────────────────
   Private, durable in this browser, and never sent anywhere. It is a
   <textarea> rather than a styled div so it behaves like the field it is:
   selectable, keyboard-editable, announced with its label. */
.tb3-note {
  margin-top: 26px;
  padding: 20px 22px;
  border-radius: var(--shell-r);
  border: 1px solid var(--line);
  background: var(--lift);
}
.tb3-note-h {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--t-md);
  color: var(--ink);
  margin: 0 0 4px;
}
.tb3-note-d { font-size: var(--t-xs); color: var(--ink-2); margin: 0 0 12px; }
.tb3-note textarea {
  width: 100%;
  min-height: 92px;
  resize: vertical;
  padding: 12px 14px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--lift);
  color: var(--ink);
  font: inherit;
  font-size: var(--t-sm);
  line-height: 1.55;
}
.tb3-note textarea:focus-visible {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--ring);
}
.tb3-note-s { font-size: var(--t-xs); color: var(--ink-2); margin: 8px 0 0; min-height: 1.2em; }

/* ── STICKY PANELS, RE-OFFSET ────────────────────────────────────────────
   Three panels were positioned under a bar that no longer floats. They are
   corrected here rather than in their own files, because the thing that
   changed is this shell and these files are still right about everything else
   they say. See --shell-stick.
   ──────────────────────────────────────────────────────────────────────── */
.quiz3-side,
.cr3-draft,
.track-meta { top: var(--shell-stick); }

/* ════════════════════════════════════════════════════════════════════════
   PHASE 3 — BUILD YOUR TABLE
   ------------------------------------------------------------------------
   THE MARKUP IS UNCHANGED. The form already had everything the approved
   mockup shows — a segmented progress indicator, the decision carried across
   every step with a way back to it, a note about where the answers go, and a
   summary column that fills as the steps are answered. What it did not have
   was the approved surface, so this is a restyle and not a rebuild: no new
   question, no new field, no reordering, no change to what is stored.
   ════════════════════════════════════════════════════════════════════════ */

.quiz3-title,
.quiz3-q {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.14;
}

/* ── THE DECISION, CARRIED IN ITS OWN PANEL ──────────────────────────────
   The context row was a line of small print above the progress bar. The
   approved form gives it a surface, because it is the one thing on the page
   that came from the reader rather than from the form — and the panel is
   where "edit it" belongs.

   IT STAYS QUIET WHEN IT IS EMPTY. `.is-empty` is the italic placeholder the
   row already used for "no subject yet"; the panel keeps that distinction
   instead of drawing a filled card around nothing. */
.quiz3-ctx {
  padding: 13px 16px;
  border-radius: 14px;
  background: var(--lav-1);
  border: 1px solid var(--line);
}
.quiz3-ctx:has(.quiz3-ctx-t.is-empty) {
  background: none;
  border-color: transparent;
  padding-inline: 0;
}

/* The note under a text answer. It says where the answer goes, so it reads as
   a fact about storage rather than as a disclaimer. */
.quiz3-privacy {
  margin-top: 12px;
  padding: 10px 14px;
  border-radius: 12px;
  background: var(--lav-1);
  color: var(--ink-2);
  font-size: var(--t-xs);
  line-height: 1.6;
}

/* The summary column gets the card the mockup draws around it. */
.quiz3-side {
  padding: clamp(18px, 2vw, 26px);
  border-radius: var(--shell-r);
  border: 1px solid var(--line);
  background: var(--lift);
}

/* product.css already un-sticks and centres this column below 900px. Nothing
   is repeated here; the card above applies on the phone too, where the column
   is already capped at 320px and centred.
   ──────────────────────────────────────────────────────────────────────── */

/* ── `.stage` INSIDE THE SHELL ───────────────────────────────────────────
   Every screen's outermost element is a `.stage`, and base.css gives it
   `padding: calc(--s8 + 40px) var(--gutter) --s9` plus `min-height: 100vh`.
   All three were right for a page that WAS the window:

     · the 124px top cleared the fixed bar,
     · `--gutter` was the page's own margin,
     · 100vh kept a short page from collapsing above the footer.

   Inside the shell all three are wrong, and visibly so. `.shell-main` already
   gutters the column, so the horizontal padding was applied twice — up to
   128px of margin on a desktop and 36px on a 320px phone. The bar no longer
   floats, so the 124px was a gap under nothing. And `.shell` is already
   `min-height: 100dvh`, so a second full-height box inside it pushed the
   content down a second time.

   `.stage--full` IS LEFT ALONE. It centres its content in the window on
   purpose — it is what the pre-shell screens use — and it sets its own
   padding and height after this.
   ──────────────────────────────────────────────────────────────────────── */
.shell .stage {
  padding-inline: 0;
  padding-top: clamp(10px, 1.6vw, 22px);
  min-height: 0;
}

/* ── THE CRUMB SCROLLS, BECAUSE NOTHING IN THIS SHELL FLOATS ─────────────
   system.css pins the path with `position: fixed; top: 64px; left: 0`, which
   was right when the top bar was fixed at 64px and spanned the window. In
   the shell the bar scrolls with the page and the window is split by a 248px
   rail — so a fixed, full-width crumb printed itself ACROSS THE NAVIGATION,
   two lines under the wordmark, on every screen except Home.

   It is a child of `.shell-main`, which already gutters the column, so in
   flow it needs no padding of its own and lands exactly above the heading
   it describes. */
.shell .crumbs {
  position: static;
  inset: auto;
  z-index: auto;
  padding: 0;
  pointer-events: auto;
}

/* ── THE CLOSING BLOCK AT PHONE WIDTH ────────────────────────────────────
   `.nextstep-mark` turns into a single grid COLUMN below 760px, so its two
   children are laid out side by side at their intrinsic widths — about 300px
   together, which does not fit a 320px phone once the column is guttered. It
   is the one element that still pushed the page wider than the viewport.

   It goes back to stacking at the width where it stops fitting, rather than
   being allowed to shrink: both children are marks, and a squeezed mark is
   worse than a stacked one. */
@media (max-width: 420px) {
  .nextstep-mark { grid-auto-flow: row; gap: 12px; }
}

/* ── THE SEARCH SUGGESTIONS ──────────────────────────────────────────────
   `repeat(auto-fit, minmax(300px, 1fr))` sets a FLOOR of 300px, not a target.
   `auto-fit` drops to one column when two no longer fit, but it never makes
   that one column narrower than its minimum — so inside a 288px column the
   track stayed 300px and the list pushed the page sideways.

   This is the same fault, and the same fix, as the Stories grid in phase 2:
   the floor has to yield to the container. `min(300px, 100%)` is the floor
   everywhere there is room for it and the container everywhere there is not.
   ──────────────────────────────────────────────────────────────────────── */
.sit-list { grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); }

/* ── THE FIELD LIST AT PHONE WIDTH ───────────────────────────────────────
   app.css already collapses `.fitem` to one column below 900px, but writes
   that column as `1fr`. A grid item's automatic minimum is `min-content`, so
   a `1fr` track is a floor, not a ceiling: the row grew to whatever its
   widest child wanted and carried the page with it.

   `minmax(0, 1fr)` is the same single column with a real minimum of zero, so
   the text inside wraps instead of the row widening. base.css already makes
   this correction for `.track` and says so in its own comment; this is the
   one place in the product that still had the uncorrected form.
   ──────────────────────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  .fitem { grid-template-columns: minmax(0, 1fr); }
}

/* ── THE CLOSING BLOCK'S OWN ACTIONS ─────────────────────────────────────
   TWO FIXES, AND THE SECOND IS THE ONE THAT MATTERS. `.act` is `nowrap`,
   which is right for "Wróć do Stołu" and impossible for the English label
   "Or describe a decision you have in front of you" — 328px on one line
   inside a 288px column. In Polish the page fitted; in English it did not,
   which is the shape of bug a single-language check never finds.

   The track minimum is corrected as well. A `1fr` column takes its automatic
   minimum from its content, so ANY future label long enough to not fit would
   widen the page again. `minmax(0, 1fr)` makes that structurally impossible
   rather than true for today's strings.
   ──────────────────────────────────────────────────────────────────────── */
@media (max-width: 760px) {
  .nextstep { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 560px) {
  .nextstep-a { width: 100%; }
  .nextstep-a .act { white-space: normal; text-align: left; }
}

/* ════════════════════════════════════════════════════════════════════════
   PHASE 5 — THE ACCOUNT THAT IS NOT ONE
   ------------------------------------------------------------------------
   Everything on this page belongs to the reader and lives in their browser.
   The approved mockup heads it like a profile; the page opens instead by
   saying what it is, because the resemblance is exactly the problem.
   ════════════════════════════════════════════════════════════════════════ */

/* NOT A WARNING STRIPE. It is the lavender the rest of the reader's own
   surfaces use — the Table's banner, the form's context panel — because this
   is a fact about where their things are kept, not an alert about a risk
   they have run into. A red or amber panel here would read as something
   having gone wrong. */
.my-local {
  margin: 26px 0 8px;
  padding: 22px 24px;
  border-radius: var(--shell-r);
  background: var(--lav-1);
  border: 1px solid var(--line);
  max-width: 68ch;
}
.my-local-t {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--t-md);
  color: var(--ink);
  margin: 0 0 8px;
}
.my-local-d {
  margin: 0;
  font-size: var(--t-sm);
  line-height: 1.65;
  color: var(--ink-2);
}

.my-count { margin: 0 0 14px; }

/* WHAT THE GATE REMOVED, SAID IN THE SAME BREATH AS THE COUNT. Quiet, and
   deliberately not an error colour: an author withdrawing consent is the
   system working, not a fault the reader has to resolve. */
.my-gone { color: var(--ink-3); }

/* The saved grid is the catalogue's grid. One rule, two pages — the same
   reason `.home3-lib` reuses it. */
.my-local + .mysec { margin-top: 34px; }

/* ════════════════════════════════════════════════════════════════════════
   PHASE 6 — THE SECOND COLUMN, WHICH THE SHELL ALREADY HAS
   ------------------------------------------------------------------------
   `.tracks` is a two-column editorial layout: a narrow sticky aside carrying
   a kicker and one line of small print, beside the content. Five screens use
   it — questions, privacy, trust, the atlas and a person.

   IT WAS RIGHT WHEN THE PAGE WAS THE WINDOW, and it is wrong now. The shell
   already spends 248px on a navigation column; a second narrow column beside
   it leaves the content fighting for what is left, and on the approved
   layouts there is no such column at all.

   RESTYLED RATHER THAN REWRITTEN, DELIBERATELY. Changing five screens'
   markup would mean touching five screens' assertions to gain exactly the
   layout this one rule produces. The aside becomes a standfirst above the
   heading — which is the order it is already written in — and the column
   lines up with `.pg` so every screen in the product shares one measure.
   ════════════════════════════════════════════════════════════════════════ */

.shell .tracks {
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  max-width: var(--shell-max);
  margin: 0 auto;
  padding-top: 40px;
}

/* Nothing floats over it any more, and it is no longer beside anything to
   stay level with — so it stops being sticky rather than being re-offset. */
.shell .track-meta {
  position: static;
  max-width: 62ch;
  margin-bottom: clamp(18px, 2.4vw, 28px);
}

/* The aside's small print is a standfirst now, so it reads at the size the
   other screens give `.pg-sub` instead of the 22ch column it was squeezed
   into. The width cap lived in an inline style on each screen; this
   overrides it in one place. */
.shell .track-meta .xs {
  max-width: 62ch !important;
  font-size: var(--t-sm);
  line-height: 1.65;
}

/* The headings on these five screens are the v2 display sizes. Inside the
   shell they share the catalogue's serif, so a reader moving between
   `#/stories` and `#/privacy` does not cross a typographic border. */
.shell .tracks > div > h1,
.shell .tracks > div > .xl,
.shell .tracks > div > .lg {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

/* ════════════════════════════════════════════════════════════════════════
   PHASE 7 — ADD YOUR OWN PATH
   ------------------------------------------------------------------------
   THE FLOW IS NOT TOUCHED, AND THAT IS THE POINT. Three stages, ten optional
   questions, a draft that saves itself, a preview that shows the reader
   exactly what another person would read, and two separate sharing questions
   — all of it already works and all of it is covered by `testContribute`.
   What it did not have was the shell's own measure and heading face, so this
   is a restyle: no new field, no reordering, and no change to what is
   written or to what `Przekaż do sprawdzenia` does.

   NOTHING HERE MAKES THE BUTTON PROMISE MORE. There is still no reviewer, no
   queue and nowhere to send a story, and the copy that says so is untouched.
   ════════════════════════════════════════════════════════════════════════ */

.shell .cr3 { max-width: var(--shell-max); }

.shell .cr3-h,
.shell .cr3-done h1 {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

/* ════════════════════════════════════════════════════════════════════════
   PHASE 8 — SETTINGS, AND THE ONE THING THAT IS NOT BUILT
   ------------------------------------------------------------------------
   Privacy and Trust are the settings surface, and they already carry real
   controls: the privacy choices write through `setPrivacy` to this browser,
   and the block list is real and reversible. They come onto the shell's
   measure through the `.tracks` rule above, which is all phase 8 needs them
   to do.

   NOTIFICATIONS ARE DELIBERATELY ABSENT. The approved design has a
   notifications screen. There is nothing to notify anybody about: no server,
   no delivery, no second person, and a question saved here reaches nobody —
   which `Conversations` states on its own page. A notifications screen would
   be a list that is empty forever, or worse, one populated to look alive.
   `T.nav.notifications` still exists for the day there is something to say;
   nothing renders it, and nothing should until there is.
   ════════════════════════════════════════════════════════════════════════ */

/* The privacy controls read as settings rather than as prose: each group is
   a surface, the way the rest of the redesign treats a panel. */
.shell .pgroup {
  padding: clamp(18px, 2vw, 24px);
  border-radius: var(--shell-r);
  border: 1px solid var(--line);
  background: var(--lift);
}
/* There is no wrapper around the groups — they are siblings under one
   <section> — so the rhythm is set between them rather than by a grid gap.
   Writing `.pgroups` here would have been a rule matching nothing. */
.shell .pgroup + .pgroup { margin-top: 14px; }

/* ════════════════════════════════════════════════════════════════════════
   KONTO I POWIADOMIENIA — mockups 05 and 08
   ------------------------------------------------------------------------
   Two screens for a product with no accounts. The surfaces are the approved
   ones — lavender for what belongs to the reader, a white card for a group of
   settings — and nothing here draws a badge, an unread count, or a dot that
   fills itself.
   ════════════════════════════════════════════════════════════════════════ */

/* ── THE ACCOUNT MENU IN THE BAR ─────────────────────────────────────── */
.acctmenu { position: relative; }

/* An initial only where a name exists to take it from. With no name the
   control keeps the neutral glyph it always had. */
.nav-account.has-initial { background: var(--lav-3); border-color: transparent; }
.nav-account-i {
  font-weight: 700; font-size: var(--t-sm); color: var(--primary);
  line-height: 1;
}

.acctmenu-list {
  position: absolute;
  inset-inline-end: 0;
  top: calc(100% + 8px);
  z-index: 40;
  min-width: 232px;
  display: grid;
  padding: 6px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--lift);
  box-shadow: var(--shadow-2);
}
.acctmenu-list[hidden] { display: none; }

.acctmenu-item {
  min-height: 44px;
  padding: 10px 14px;
  border: 0;
  border-radius: 10px;
  background: none;
  color: var(--ink-2);
  font: inherit;
  font-size: var(--t-sm);
  text-align: left;
  cursor: pointer;
}
.acctmenu-item:hover { background: var(--wash-2); color: var(--ink); }

/* The last entry erases this browser and its document. It is marked as the
   consequential one — it is not a sign-out and must not read like one. */
.acctmenu-item:last-child { color: var(--danger); }
.acctmenu-item:last-child:hover { background: var(--danger-dim); color: var(--danger); }

/* ── THE ACCOUNT SCREEN ──────────────────────────────────────────────── */
.acct-head { margin-bottom: 8px; }

/* WHAT THIS PAGE IS, said before anything that resembles an account. The
   lavender the reader owns elsewhere — not a warning stripe, because nothing
   has gone wrong. */
.acct-truth {
  margin: 22px 0 30px;
  padding: 22px 24px;
  border-radius: var(--shell-r);
  background: var(--lav-1);
  border: 1px solid var(--line);
  max-width: 68ch;
}
.acct-truth-t {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--t-md);
  color: var(--ink);
}
.acct-truth-d { margin: 0; font-size: var(--t-sm); line-height: 1.65; color: var(--ink-2); }
.acct-truth-k { margin: 10px 0 0; font-size: var(--t-sm); font-weight: 600; color: var(--ink); }

.acct-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
  gap: 16px;
  align-items: start;
}
.acct-grid > div { display: grid; gap: 16px; align-content: start; }

.acct-group {
  padding: clamp(18px, 2vw, 24px);
  border-radius: var(--shell-r);
  border: 1px solid var(--line);
  background: var(--lift);
}
.acct-group-t {
  margin: 0 0 14px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--t-md);
  color: var(--ink);
}

.acct-label { display: block; font-size: var(--t-xs); color: var(--ink-2); margin-bottom: 6px; }

.acct-group input[type="text"],
.acct-group select {
  width: 100%;
  min-height: 44px;
  padding: 10px 14px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--lift);
  color: var(--ink);
  font: inherit;
  font-size: var(--t-sm);
}
.acct-group input[type="text"]:focus-visible,
.acct-group select:focus-visible {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--ring);
}

.acct-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 0;
}
.acct-row + .acct-row { border-top: 1px solid var(--line); }
.acct-row-b { min-width: 0; }
.acct-row-t { margin: 0; font-size: var(--t-sm); font-weight: 600; color: var(--ink); }
.acct-row-d { margin: 6px 0 0; font-size: var(--t-xs); line-height: 1.6; color: var(--ink-2); }

/* A SWITCH THAT IS A SWITCH. `role="switch"` with `aria-checked`, so its state
   is announced rather than only painted, and the knob moves as well as the
   track changing colour. */
/* THE BUTTON IS THE HIT AREA, THE SPAN IS THE SWITCH. 44px of target with a
   28px track inside it, so the control is comfortable to tap without the
   page growing a pill nobody draws that way. */
.acct-sw {
  flex: 0 0 auto;
  display: grid; place-items: center;
  width: 56px; min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  border-radius: 999px;
  cursor: pointer;
}
.acct-sw-t {
  display: grid; align-items: center;
  width: 46px; height: 28px;
  padding: 3px;
  border-radius: 999px;
  border: 1px solid var(--line-2);
  background: var(--lift-2);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.acct-sw-k {
  display: block;
  width: 20px; height: 20px;
  border-radius: 999px;
  background: var(--ink-4);
  transition: transform var(--dur) var(--ease), background var(--dur) var(--ease);
}
.acct-sw.is-on .acct-sw-t { background: var(--primary); border-color: var(--primary); }
.acct-sw.is-on .acct-sw-k { transform: translateX(18px); background: #fff; }
.acct-sw:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--ring); }

.acct-status { margin: 10px 0 0; font-size: var(--t-xs); color: var(--ink-2); min-height: 1.2em; }

.acct-group .btn-primary,
.acct-group .btn-quiet,
.acct-group .btn-danger { margin-top: 12px; }

/* The erase control. Destructive, and it looks it — but it is a button, not
   an alarm: the copy beside it carries the warning. */
.btn-danger {
  min-height: 44px;
  padding: 11px 20px;
  border-radius: var(--r-btn);
  border: 1px solid var(--danger);
  background: var(--danger-dim);
  color: var(--danger);
  font: inherit;
  font-size: var(--t-sm);
  font-weight: 600;
  cursor: pointer;
}
.btn-danger:hover { background: var(--danger); color: #fff; }
.btn-danger[disabled] { opacity: .5; cursor: default; }

/* ── POWIADOMIENIA ───────────────────────────────────────────────────── */
.nt-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin: 24px 0 18px; }
.nt-tab {
  min-height: 44px; padding: 10px 16px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--lift); color: var(--ink-2);
  font: inherit; font-size: var(--t-sm); font-weight: 600;
  cursor: pointer;
}
.nt-tab:hover { border-color: var(--primary); color: var(--primary); }
.nt-tab.is-on { background: var(--primary); border-color: var(--primary); color: #fff; }

.nt-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }

.nt-row {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 18px 20px;
  border-radius: var(--shell-r);
  border: 1px solid var(--line);
  background: var(--lift);
}
.nt-row-i { flex: 0 0 auto; padding-top: 5px; }

/* A DOT THAT MEANS A KIND, NOT AN UNREAD. There is no unread state in this
   product and this mark never changes once the row exists. */
.nt-dot { display: block; width: 9px; height: 9px; border-radius: 999px; background: var(--ink-4); }
.nt-dot.is-questions { background: var(--primary); }
.nt-dot.is-stories { background: var(--ok); }

.nt-row-b { min-width: 0; }
.nt-row-t { margin: 0; font-size: var(--t-sm); font-weight: 700; color: var(--ink); }
.nt-row-d { margin: 6px 0 0; font-size: var(--t-sm); line-height: 1.6; color: var(--ink-2); }
.nt-row-a {
  margin-top: 12px; min-height: 44px;
  background: none; border: 0; padding: 4px 2px;
  color: var(--primary); font: inherit; font-size: var(--t-sm); font-weight: 600;
  text-decoration: underline; cursor: pointer;
}

.nt-empty {
  padding: 30px;
  border-radius: var(--shell-r);
  border: 1px solid var(--line);
  background: var(--lav-1);
}
.nt-empty-t {
  margin: 0 0 8px;
  font-family: var(--font-display); font-weight: 600; font-size: var(--t-lg);
  color: var(--ink);
}
.nt-empty-d { margin: 0 0 18px; font-size: var(--t-sm); line-height: 1.6; color: var(--ink-2); }

/* SAID UNDER THE LIST EVERY TIME. Not an empty state — a standing fact. */
.nt-note {
  margin-top: 26px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  font-size: var(--t-xs);
  line-height: 1.7;
  color: var(--ink-2);
  max-width: 64ch;
}

@media (max-width: 560px) {
  .acct-row { flex-wrap: wrap; }
  .acctmenu-list { min-width: 200px; }
}

/* ════════════════════════════════════════════════════════════════════════
   HOME — THE APPROVED HERO (mockup 01)
   ------------------------------------------------------------------------
   WHAT THIS CHANGES, AND WHY IT IS HERE RATHER THAN IN product.css.

   product.css draws a CENTRED hero: a 940px column, text-align centre, the
   field on its own line, the chips under it, two buttons under those, and the
   table drawing in a separate section further down the page, below the story
   cards. The approved design is a different shape, not a different skin — one
   lavender panel, text left, the drawing beside the words, the action inside
   the field, and the chips and the second action ranged left underneath.

   So this is the redesign layer doing what the redesign layer does: shell.css
   loads after product.css and claims the surfaces the approved mockups cover.
   Nothing in product.css is deleted, and a screen this file does not name is
   untouched.
   ════════════════════════════════════════════════════════════════════════ */

/* The stage already pads. A second gutter here inset the hero from the
   section below it, so the panel and the story cards never lined up. */
.shell .home3 { padding-inline: 0; padding-top: 0; }

/* THE LOOSE PLANT GOES. product.css anchors it 248px from the bottom of
   `.home3`, which was measured against a page that ended with the table
   scene. The scene is in the hero now, so 248px lands it under the first
   story card, where it showed as a grey arc poking out of the corner.
   The hero's own drawing is the illustration this layout has. */
.shell .home3-plant { display: none; }

.home3-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(200px, 31%, 380px);
  gap: clamp(12px, 2.2vw, 34px);
  align-items: center;

  /* The centred column, undone. */
  max-width: none;
  margin: 0;
  text-align: left;

  padding: clamp(22px, 2.8vw, 42px);
  background: var(--lav-1);
  border: 1px solid var(--line);
  border-radius: var(--shell-r);
}

.home3-hero-b,
.home3-hero-art { min-width: 0; }
/* product.css hides the narrow drawing above the phone breakpoint, because
   there it was the phone's copy of a desktop band. In the hero it is the only
   copy, at every width. */
.home3-hero-art .home3-svg.is-narrow { display: block; width: 100%; height: auto; }
.home3-hero-art .home3-svg.is-wide { display: none; }

.home3-h1 {
  font-family: var(--font-display);
  font-size: clamp(30px, 3.4vw, 46px);
  font-weight: 700;
  letter-spacing: -.012em;
  line-height: 1.12;
  text-wrap: balance;
}

.home3-sub {
  margin: 12px 0 0;
  max-width: 46ch;
  font-size: clamp(15px, 1.15vw, 18px);
}

.home3-form { margin-top: clamp(16px, 2.1vw, 26px); }

/* ONE PILL HOLDS THE PROMPT AND THE ACTION. */
.home3-field {
  width: min(560px, 100%);
  margin: 0;
  gap: 10px;
  padding: 6px 6px 6px 18px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--lift);
  box-shadow: var(--shadow-1);
}
.home3-input { padding: 12px 0; }
.home3-go {
  flex: 0 0 auto;
  padding: 13px 22px;
  font-size: var(--t-sm);
  white-space: nowrap;
}

.home3-chips { justify-content: flex-start; margin-top: 14px; }

.home3-cta { justify-content: flex-start; margin-top: 14px; gap: 12px; }
.home3-stories {
  min-height: 44px;
  padding: 11px 20px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  background: var(--lift);
  /* NOT `--primary`. The accent is correct as a fill and measures 3.16 : 1 as
     TEXT on the dark theme's card — the exact case `--violet-text` exists
     for, so this takes the token rather than repeating the mistake it was
     introduced to fix. 5.54 : 1 light, 7.29 dark. */
  color: var(--violet-text);
  font-weight: 600;
}
.home3-stories:hover { border-color: var(--primary); background: var(--lav-1); }

/* ── THE PHONE ───────────────────────────────────────────────────────────
   One column, and the drawing stands down: the approved phone screen does
   not carry it, and at 375px it would be a 40px-tall smudge. Its description
   stays in the DOM for assistive tech. */
@media (max-width: 860px) {
  .home3-hero {
    grid-template-columns: minmax(0, 1fr);
    padding: clamp(18px, 4vw, 26px);
  }
  .home3-hero-art .home3-svg.is-narrow { display: none; }

  /* THE BUTTON TAKES ITS OWN ROW rather than squeezing the field to nothing.
     `min-width: 58%` on the input is what forces the wrap: the button can no
     longer fit beside it, so it drops. */
  .home3-field { flex-wrap: wrap; border-radius: var(--shell-r); padding: 6px 6px 6px 16px; }
  .home3-input { flex: 1 1 58%; min-width: 58%; }
  .home3-go { flex: 1 1 100%; justify-content: center; margin-top: 4px; }
  .home3-stories { width: 100%; justify-content: center; }
}

/* ════════════════════════════════════════════════════════════════════════
   TWORZENIE STOŁU — THE PROGRESS BAR (mockups 02 and 07)
   ------------------------------------------------------------------------
   product.css draws progress as five separate dashes with the count on the
   right. The approved design draws ONE continuous track with a filled
   portion and the count on the left — which is also the clearer reading:
   five dashes say "five things", a filled track says "this far through".

   THE NUMBER OF STEPS IS NOT CHANGED. The mockup happens to say "Krok 2 z 3"
   because that is what its example shows; this quiz has five questions, two
   of them skippable, and that is product logic rather than a drawing. Only
   the shape of the indicator moves.
   ════════════════════════════════════════════════════════════════════════ */

.quiz3-prog { gap: 16px; }

/* The count reads first, as the mockup has it. `order` rather than reordering
   the DOM: the markup's order is the reading order for a screen reader, and
   "Krok 1 z 5" after the bar is the right thing to hear. */
.quiz3-prog-n { order: -1; color: var(--ink-2); }

.quiz3-bar {
  gap: 0;
  height: 8px;
  max-width: 420px;
  background: var(--lav-2);
  border-radius: var(--r-pill);
  overflow: hidden;
}

.quiz3-seg {
  height: 100%;
  border: 0;
  border-radius: 0;
  background: transparent;
}

/* Finished and current are the same fill here. They were two hues because
   five separate dashes needed to distinguish "done" from "you are here"; a
   continuous track says that with its own edge. The current segment keeps a
   rounded right end, which is what gives the fill its cap — its left half
   sits under the finished run, so the join does not show. */
.quiz3-seg.is-done,
.quiz3-seg.is-on { background: var(--primary); border: 0; }
.quiz3-seg.is-on { border-radius: var(--r-pill); }

/* ════════════════════════════════════════════════════════════════════════
   MÓJ STÓŁ — THE APPROVED TABLE (mockup 03)
   ------------------------------------------------------------------------
   product.css draws the Table as a drawing: a three-column, two-row grid
   with an oval in the middle of the first row, two seats flanking it, a
   third underneath, and SVG hairlines joining them. The approved design is
   a row of equal cards, each carrying what it shares with the reader's
   situation and what it does not.

   WHAT MOVED AND WHY, in one line each:
     the oval and the wires   gone — they cost the cards their width
     the title                left, with the privacy badge on its own line
     the card                 title, road, stage, the two facets, one action
     `Poznaj historię`        a filled button, as the mockup draws it

   product.css keeps every rule it had. `.tb3-stage.is-grid` is the opt-in:
   the sample Table at `#/table/...` does not carry it and still draws the
   oval, which is its own screen and has the room for one.
   ════════════════════════════════════════════════════════════════════════ */

/* ── THE HEAD ────────────────────────────────────────────────────────── */
.tb3-head {
  max-width: none;
  margin: 0;
  text-align: left;
}

.tb3-title-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
}

.tb3-title {
  font-family: var(--font-display);
  font-size: clamp(26px, 3vw, 40px);
  font-weight: 700;
  letter-spacing: -.015em;
  line-height: 1.12;
  margin: 6px 0 0;
}

/* The badge and `Edytuj kontekst` share the rest of the title's row: the
   badge sits with the question, the edit link goes to the far edge. When the
   question is long enough to take the whole line they wrap together and keep
   the same relationship to each other. */
.tb3-title-row .tb3-topline {
  margin: 0;
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
}

.tb3-chips { justify-content: flex-start; }
.tb3-lead { margin-inline: 0; }
.tb3-privnote { margin-top: 10px; color: var(--ink-3); }

/* ── THE ROW OF CARDS ────────────────────────────────────────────────── */
.tb3-stage.is-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(272px, 100%), 1fr));
  column-gap: clamp(12px, 1.4vw, 20px);
  row-gap: clamp(12px, 1.4vw, 20px);
  grid-template-rows: none;
  align-items: stretch;
  max-width: none;
  margin: clamp(16px, 2vw, 26px) 0 0;
}

.tb3-stage.is-grid .tb3-seats { display: contents; }

/* The seats were placed by hand into named grid cells. In a row they are
   just cells, in DOM order — which is the order the composition produced. */
.tb3-stage.is-grid .tb3-seat,
.tb3-stage.is-grid .tb3-seat.is-p0,
.tb3-stage.is-grid .tb3-seat.is-p1,
.tb3-stage.is-grid .tb3-seat.is-p2 {
  grid-column: auto;
  grid-row: auto;
  display: flex;
}

/* The endpoint dots had hairlines to meet. There are none now, so a dot on
   the edge of a card is a dot on the edge of a card. */
.tb3-stage.is-grid .tb3-seat::before,
.tb3-stage.is-grid .tb3-seat::after { display: none; }

.tb3-stage.is-grid .tb3-card,
.tb3-stage.is-grid .tb3-empty {
  display: flex;
  flex-direction: column;
  width: 100%;
}

/* ── ONE CARD ────────────────────────────────────────────────────────── */
.tb3-card-h { align-items: flex-start; }

.tb3-story {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--t-md);
  line-height: 1.25;
  letter-spacing: -.01em;
  color: var(--ink);
  margin: 15px 0 0;
  overflow-wrap: anywhere;
}

/* Demoted from the heading, where the title now is. */
.tb3-route {
  margin: 5px 0 0;
  font-size: var(--t-xs);
  font-weight: 500;
  color: var(--ink-2);
}

/* The stage of the journey, as the chip the mockup draws. */
.tb3-shape {
  display: inline-block;
  align-self: flex-start;
  margin: 10px 0 0;
  padding: 5px 12px;
  border-radius: var(--r-pill);
  background: var(--lav-2);
  color: var(--chip-ink);
  font-size: var(--t-xs);
  font-weight: 600;
}

/* ── THE TWO FACETS ──────────────────────────────────────────────────── */
.tb3-facets {
  display: grid;
  gap: 12px;
  margin-top: 15px;
  padding-top: 15px;
  border-top: 1px solid var(--line);
}

.tb3-facet { display: flex; align-items: flex-start; gap: 10px; }
.tb3-facet-i { flex: 0 0 auto; padding-top: 1px; color: var(--violet-text); }
.tb3-facet-b { min-width: 0; }
.tb3-facet-k { margin: 0; font-size: var(--t-xs); font-weight: 700; color: var(--ink); }
.tb3-facet-v { margin: 3px 0 0; font-size: var(--t-xs); line-height: 1.55; color: var(--ink-2); }

/* AN ABSENCE LOOKS LIKE ONE. When the engine recorded nothing on this side
   the row still appears — a reader is owed the fact that we looked — but it
   is quiet, and the sentence in it is the product saying so rather than a
   finding. */
.tb3-facet.is-absent .tb3-facet-i { color: var(--ink-4); }
.tb3-facet.is-absent .tb3-facet-v { font-style: italic; color: var(--ink-3); }

/* ── THE ACTIONS ─────────────────────────────────────────────────────── */
.tb3-foot {
  margin-top: auto;
  padding-top: 15px;
  display: flex;
  flex-direction: column-reverse;
  align-items: stretch;
  gap: 10px;
}

/* `Poznaj historię` is the card's one action and the approved design fills
   it. White on `--primary` measures 5.81 : 1, so it needs no correction
   from quality.css — which is why section 11c no longer names it. */
.tb3-open {
  min-height: 44px;
  justify-content: center;
  gap: 8px;
  padding: 11px 18px;
  border-radius: var(--r-btn);
  background: var(--primary);
  color: var(--primary-ink);
  font-weight: 600;
  margin-inline: 0;
}
.tb3-open:hover { background: var(--primary-lit); color: var(--primary-ink); }

/* `Dlaczego ta historia?` stays a text control. It reveals, it does not
   navigate, and two filled buttons on one card would make them argue. */
.tb3-why {
  justify-content: space-between;
  padding: 6px 2px;
  margin-inline: 0;
  min-height: 44px;
}

/* ── THE READER'S OWN NOTE ───────────────────────────────────────────── */
.tb3-note {
  margin-top: clamp(20px, 2.4vw, 30px);
  padding: clamp(16px, 1.8vw, 22px);
  border: 1px solid var(--line);
  border-radius: var(--shell-r);
  background: var(--lift);
  display: grid;
  grid-template-columns: minmax(180px, 260px) minmax(0, 1fr);
  gap: 6px clamp(16px, 2vw, 28px);
  align-items: start;
}
.tb3-note-h {
  grid-column: 1;
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--t-md);
  color: var(--ink);
}
.tb3-note-d {
  grid-column: 1;
  margin: 4px 0 0;
  font-size: var(--t-xs);
  line-height: 1.55;
  color: var(--ink-3);
}
.tb3-note textarea {
  grid-column: 2;
  grid-row: 1 / span 2;
  width: 100%;
  min-height: 86px;
  padding: 12px 14px;
  border: 1px solid var(--line-2);
  border-radius: 12px;
  background: var(--lift);
  color: var(--ink);
  font: inherit;
  font-size: var(--t-sm);
  resize: vertical;
}
.tb3-note textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--ring);
}
.tb3-note-s { grid-column: 2; margin: 8px 0 0; font-size: var(--t-xs); color: var(--ink-2); }

/* ── THE PHONE ───────────────────────────────────────────────────────── */
@media (max-width: 760px) {
  .tb3-title-row .tb3-topline { margin-inline-start: 0; width: 100%; }
  .tb3-note { grid-template-columns: minmax(0, 1fr); }
  .tb3-note-h, .tb3-note-d, .tb3-note textarea, .tb3-note-s { grid-column: 1; }
  .tb3-note textarea { grid-row: auto; margin-top: 12px; }
}

/* ════════════════════════════════════════════════════════════════════════
   TWORZENIE STOŁU — PODSUMOWANIE (mockup 02)
   ------------------------------------------------------------------------
   The column beside the questions. It held a drawing of a table filling up;
   it now holds the answers themselves, each one the way back to the question
   it came from. See `Summary` in screens/Onboarding.js for what may appear
   in it and what may not.
   ════════════════════════════════════════════════════════════════════════ */

/* product.css sticks this column 104px down, which was the height of a top
   bar that no longer floats. In the shell that is a gap under nothing. */
.shell .quiz3-side { top: var(--shell-stick); }

.qsum {
  padding: clamp(16px, 1.8vw, 22px);
  border: 1px solid var(--line);
  border-radius: var(--shell-r);
  background: var(--lift);
}

.qsum-h {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--t-md);
  color: var(--ink);
}
.qsum-d {
  margin: 6px 0 0;
  font-size: var(--t-xs);
  line-height: 1.55;
  color: var(--ink-3);
}

.qsum-list { list-style: none; margin: 12px 0 0; padding: 0; }
.qsum-list > li + li { border-top: 1px solid var(--line); }

/* THE WHOLE ROW IS THE CONTROL, not a small `Edytuj` beside it: the target is
   the thing somebody is already looking at, and at 44px tall it is reachable
   with a thumb. The chevron says it leads somewhere; the accessible name says
   where. */
.qsum-row {
  display: flex;
  width: 100%;
  min-height: 44px;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 8px;
  margin-inline: -8px;
  width: calc(100% + 16px);
  border: 0;
  border-radius: 10px;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.qsum-row:hover { background: var(--wash-2); }
.qsum-row:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--ring); }

.qsum-b { flex: 1 1 auto; min-width: 0; }
.qsum-k { display: block; font-size: var(--t-xs); font-weight: 700; color: var(--ink); }
.qsum-v {
  display: block;
  margin-top: 3px;
  font-size: var(--t-xs);
  line-height: 1.5;
  color: var(--ink-2);
  overflow-wrap: anywhere;
}

/* Several chosen areas are a list, because that is what they are. */
.qsum-vs {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  display: grid;
  gap: 2px;
  font-size: var(--t-xs);
  line-height: 1.5;
  color: var(--ink-2);
}
.qsum-vs li::before { content: "\2022 "; color: var(--ink-4); }

.qsum-c { flex: 0 0 auto; padding-top: 2px; color: var(--ink-3); }

.qsum-empty {
  margin: 12px 0 0;
  font-size: var(--t-xs);
  line-height: 1.6;
  color: var(--ink-3);
}

/* ── THE PRIVACY BADGE ON THE PROGRESS ROW ───────────────────────────────
   The approved form carries the same claim the Table carries, in the same
   place the mockup puts it: the far end of the step row. It is a fact, not
   reassurance copy — there is no server for an answer to reach. */
.quiz3-prog { flex-wrap: wrap; }
.quiz3-private {
  margin-inline-start: auto;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 12px;
  border-radius: var(--r-pill);
  background: var(--lav-2);
  color: var(--chip-ink);
  font-size: var(--t-xs);
  font-weight: 600;
}

@media (max-width: 980px) {
  .quiz3-private { margin-inline-start: 0; }
}
