/* What They Meant
   A declassified inter-office memo. The product's joke — decoding what corporate
   people really mean — is the page's visual joke: a redacted document getting
   stamped and released.

   Palette is locked. Do not substitute tokens.

   Contrast rule that constrains everything below: --stamp-red is 4.3:1 on
   --paper, which is AA for LARGE text only (>=24px, or >=18.66px bold). It is
   used for the stamp, headline-scale numerals and meter fills. It is never used
   for body copy, small labels, or a button label. */

:root {
  --paper:        #E4DCC8;
  --paper-dark:   #D8CDB0;
  --ink:          #1F2420;
  --ink-soft:     #565049;
  --stamp-red:    #B33A3A;
  --redact-black: #14140F;
  --accent-olive: #3E6259;

  --display: "Special Elite", "Courier New", monospace;
  --sans: "IBM Plex Sans", ui-sans-serif, system-ui, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", monospace;

  --gutter: clamp(1.15rem, 4vw, 4rem);
  --prose: 46ch;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: clamp(16px, 0.95rem + 0.15vw, 17.5px);
  line-height: 1.55;
  /* Ultra-wide guard only. The page is genuinely full width at every ordinary
     size; this stops the board's five columns stretching on a 34" monitor. */
  max-width: 150rem;
  margin-inline: auto;
}

button, textarea { font: inherit; color: inherit; }

/* Ink, not stamp-red. A red ring around a text field reads as a validation
   error, and red is the weakest contrast in the palette anyway (4.3:1 on paper
   against ink 11.5:1). Browsers always treat a focused text input as
   focus-visible, so this ring is what people see the moment they click the box.
   On the red buttons it inverts to paper, where ink would nearly disappear. */
:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

.decode:focus-visible,
.btn-primary:focus-visible,
.chip:active:focus-visible {
  outline-color: var(--paper);
  outline-offset: 2px;
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.wide-only { display: inline; }
.narrow-only { display: none; }

@media (max-width: 480px) {
  .wide-only { display: none; }
  .narrow-only { display: inline; }
}

/* ---------- masthead ---------- */

.masthead {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .35rem 1.5rem;
  padding: 1.1rem var(--gutter);
  padding-top: max(1.1rem, env(safe-area-inset-top));
  padding-left: max(var(--gutter), env(safe-area-inset-left));
  padding-right: max(var(--gutter), env(safe-area-inset-right));
  border-bottom: 2px solid var(--redact-black);
}

.wordmark {
  font-family: var(--display);
  font-size: clamp(1rem, .85rem + .6vw, 1.35rem);
  letter-spacing: .04em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
  /* 44px touch target without changing how the wordmark looks. */
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

/* The word the product is named for, stamped: red and tilted to the same -8 deg
   as every other stamp in the system. */
.wordmark-stamp {
  display: inline-block;
  margin-inline: .12em;
  color: var(--stamp-red);
  transform: rotate(-8deg);
  transform-origin: 50% 60%;
  border: 4px solid var(--stamp-red);
}

.tagline {
  flex: 1 1 12rem;
  margin: 0;
  font-size: .85rem;
  color: var(--ink-soft);
}

.masthead-nav {
  display: flex;
  align-items: baseline;
  gap: 1.25rem;
}

/* Anchor and button share this so the two read as one nav rather than as a link
   next to a control. */
.masthead-link {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-family: var(--mono);
  font-size: .8rem;
  color: var(--accent-olive);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  /* 44px touch target without inflating the visible label. */
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.masthead-link:hover { border-bottom-color: currentColor; }

@media (max-width: 30rem) {
  .tagline { display: none; }
  .masthead { justify-content: space-between; }
}

/* ---------- workspace ---------- */

.workspace {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
  /* Bottom padding halved. Paired with the board rule below it, the old value
     left 80px above a 2px line and 66px under it -- 146px of nothing wrapped
     around a divider whose whole job is to take up no room. */
  padding: clamp(1.75rem, 5vw, 4rem) var(--gutter) clamp(1.5rem, 3vw, 2rem);
  padding-left: max(var(--gutter), env(safe-area-inset-left));
  padding-right: max(var(--gutter), env(safe-area-inset-right));
}

/* Two columns from 769px, per the brief's breakpoint table. */
@media (min-width: 769px) {
  .workspace {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    /* Stretch, not start. With start the output column was a 122px stub beside a
       531px input column, so the right half read as abandoned space rather than
       as a panel waiting for something. Stretched, the empty copy centres in a
       column the same height as its neighbour. */
    align-items: stretch;
  }
  .pane-output {
    padding-left: clamp(1.75rem, 3.5vw, 3.5rem);
    border-left: 2px solid var(--redact-black);
  }
}

.pane { min-width: 0; }

@media (min-width: 769px) {
  .pane-output { display: flex; flex-direction: column; }
  /* Centres the empty copy in the stretched column. Once a result exists the
     block below sizes normally and this has nothing left to centre. */
  .pane-output > .empty { margin-block: auto; }
}

.lede {
  margin: 0 0 clamp(1.25rem, 3vw, 2rem);
  max-width: 30ch;
  font-family: var(--display);
  font-size: clamp(28px, 5vw, 48px);
  /* 1.2, not 1.32. The extra headroom existed for a rotated box whose corners
     swung above the line; upright, the box needs only its border and padding. */
  line-height: 1.2;
  font-weight: 400;
  letter-spacing: -.01em;
}

#input {
  display: block;
  width: 100%;
  padding: clamp(.9rem, 2vw, 1.2rem);
  background: var(--paper-dark);
  color: var(--ink);
  border: 2px solid var(--redact-black);
  border-radius: 0;
  resize: vertical;
  min-height: 8rem;
}

#input::placeholder { color: var(--ink-soft); font-style: italic; opacity: 1; }

.field-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .75rem 1rem;
  margin-top: .9rem;
}

.count {
  font-family: var(--mono);
  font-size: .78rem;
  color: var(--ink-soft);
}

.decode {
  flex: 1 1 auto;
  min-height: 44px;
  max-width: 18rem;
  padding: .8rem 1.75rem;
  background: var(--stamp-red);
  /* White, not --paper: --paper on --stamp-red only clears the large-text bar,
     and a button label is not large text. White gets 5.9:1. */
  color: #fff;
  border: 2px solid var(--stamp-red);
  border-radius: 0;
  font-family: var(--mono);
  font-size: .85rem;
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
  cursor: pointer;
}

.decode:hover:not(:disabled) { background: var(--redact-black); border-color: var(--redact-black); }
.decode:disabled { opacity: .55; cursor: default; }

.decode .arrow {
  display: inline-block;
  transition: transform .15s ease-out;
}

.decode:hover:not(:disabled) .arrow { transform: translateX(3px); }

.error {
  margin: .75rem 0 0;
  font-size: .9rem;
  color: var(--stamp-red);
  font-weight: 600;
}

.error:empty { display: none; }

.assurance {
  max-width: var(--prose);
  margin: 1.5rem 0 0;
  font-size: .85rem;
  color: var(--ink-soft);
}

/* ---------- the document ---------- */

.doc {
  position: relative;
  /* Queried below. Whether the stamp can overlap depends on how wide THIS panel
     is, not how wide the window is -- at 1265px the window looks roomy while the
     panel is under 500px. */
  container-type: inline-size;
  padding: clamp(1.25rem, 3vw, 2rem);
  background: var(--paper-dark);
  border: 2px solid var(--redact-black);
}

/* No label above the quote — the frame and the italic carry it. */
.said {
  margin: 0;
  font-style: italic;
  font-size: clamp(1rem, .95rem + .3vw, 1.15rem);
  color: var(--ink-soft);
}

/* The divider IS the label: a redaction bar between what was said and what was
   meant. In the reveal it sweeps across the translation and wipes away. */
.redaction {
  height: 12px;
  margin: 1.25rem 0;
  background: var(--redact-black);
}

.meant {
  margin: 0;
  font-size: clamp(1.35rem, 1rem + 1.6vw, 2rem);
  line-height: 1.2;
  font-weight: 600;
  color: var(--ink);
}

.savage {
  margin: 1rem 0 0;
  font-family: var(--mono);
  font-size: clamp(.82rem, .78rem + .2vw, .95rem);
  line-height: 1.45;
  color: var(--accent-olive);
}

.savage:empty { display: none; }

/* ---------- meters ---------- */

.meters {
  display: grid;
  gap: .6rem;
  margin-top: 1.75rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--ink-soft);
}

.meter {
  display: grid;
  grid-template-columns: minmax(0, 9rem) 1fr 2.5rem;
  align-items: center;
  gap: .75rem;
}

.meter[hidden] { display: none; }

.meter-name {
  font-size: .8rem;
  color: var(--ink-soft);
}

/* Ten cells, not a bar. A continuous progress bar is the SaaS-dashboard pattern
   the brief rules out; a row of cells blacked out one at a time reads as a
   censored line, which is the only chart shape that belongs in this product. */
.meter-cells {
  display: flex;
  gap: 3px;
  height: 14px;
}

.cell {
  flex: 1;
  position: relative;
  overflow: hidden;
  border: 1px solid var(--ink-soft);
  background: var(--paper);
}

.cell-fill {
  position: absolute;
  inset: 0;
  width: 0;
  background: var(--stamp-red);
  transition: width .26s ease-out;
}

/* The second measurement is a different measurement, so it gets a different
   colour. Two red rows of similar length read as one repeated number. */
#cellsPa .cell-fill { background: var(--accent-olive); }

/* The numeral is --ink, never --stamp-red: at this size stamp-red fails AA. */
.meter-num {
  font-family: var(--mono);
  font-size: .85rem;
  text-align: right;
  color: var(--ink);
}

/* ---------- stamp ---------- */

.stamp {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: .1rem;
  margin-top: 1.5rem;
  padding: .5rem 1.1rem;
  border: 4px solid var(--stamp-red);
  color: var(--stamp-red);
  font-family: var(--display);
  text-align: center;
  transform: rotate(-8deg);
  transform-origin: center;
  /* FIXED width, not max-width. As a shrink-to-fit box the stamp sized itself
     from the label while the label sized itself from the stamp, so the JS that
     shrinks the label to fit had no stable target and long words overflowed the
     border. A fixed box also matches the 280x120 badge on the exported card. */
  width: min(15rem, 100%);
  max-width: 100%;
}

/* Break between words only. overflow-wrap:anywhere split "SURVEILLANCE" across
   two lines mid-word, which reads as a rendering fault rather than a stamp. A
   single word that still will not fit is handled by the font-size clamp. */
.stamp-label { overflow-wrap: normal; hyphens: none; }

.stamp[hidden] { display: none; }

/* 28px clears AA for stamp-red; nothing smaller may use this colour. */
.stamp-label { font-size: clamp(18px, 1rem + 1vw, 28px); line-height: 1.1; }
.stamp-score { font-size: clamp(15px, .9rem + .5vw, 20px); }

/* The stamp only overlaps once the DOCUMENT is wide enough to hold the meters
   and a 240px stamp side by side. Keyed to the viewport this was wrong: a 1265px
   window gives a panel under 500px, and reserving 17rem there squeezed the ten
   meter cells to 2px each. Container query, because the answer depends on this
   panel and not on the window. */
@container (min-width: 39rem) {
  .stamp {
    position: absolute;
    right: clamp(1rem, 2vw, 2rem);
    bottom: clamp(1rem, 2vw, 2rem);
    margin-top: 0;
    background: var(--paper-dark);
  }
  .meters { padding-right: 17rem; }
}

/* Below that it sits in flow, right-aligned, clear of the meters entirely. */
@container (max-width: 38.99rem) {
  .doc { display: flex; flex-direction: column; align-items: flex-start; }
  .doc > * { width: 100%; }
  .doc > .stamp { width: min(15rem, 100%); align-self: flex-end; }
}

/* ---------- the reveal ----------
   The one orchestrated moment on the page. Bars sweep across where the
   translation will be, then wipe away to expose it. Not a fade. */

.result[data-state="revealing"] .meant,
.result[data-state="revealing"] .savage { visibility: hidden; }

.result[data-state="revealing"] .redaction {
  animation: sweep .55s cubic-bezier(.65, 0, .35, 1) forwards;
}

@keyframes sweep {
  0%   { transform: scaleY(1) translateY(0); }
  35%  { transform: scaleY(9) translateY(28%); }
  70%  { transform: scaleY(9) translateY(28%); }
  100% { transform: scaleY(1) translateY(0); }
}

.result[data-state="revealed"] .meant {
  animation: expose .3s ease-out both;
}

@keyframes expose {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.result[data-state="revealed"] .stamp {
  animation: stamp-drop .4s cubic-bezier(.2, 1.5, .4, 1) both;
}

@keyframes stamp-drop {
  0%   { opacity: 0; transform: rotate(-8deg) scale(1.6); }
  60%  { opacity: 1; transform: rotate(-8deg) scale(.94); }
  100% { opacity: 1; transform: rotate(-8deg) scale(1); }
}

/* Loading: a scanning shimmer across the panel, not a spinner. */
.result[data-state="loading"] {
  position: relative;
  overflow: hidden;
}

.result[data-state="loading"]::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 40%, rgb(255 255 255 / .38) 50%, transparent 60%);
  animation: scan 1.1s linear infinite;
  pointer-events: none;
}

@keyframes scan {
  from { transform: translateX(-100%); }
  to   { transform: translateX(100%); }
}

/* ---------- actions ---------- */

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: .7rem;
  margin-top: 1.5rem;
}

.btn {
  min-height: 44px;
  padding: .6rem 1.2rem;
  background: transparent;
  color: var(--ink);
  border: 2px solid var(--redact-black);
  border-radius: 0;
  font-family: var(--mono);
  font-size: .78rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
}

.btn:hover { background: var(--redact-black); color: var(--paper); }
.btn:disabled { opacity: .45; cursor: default; }
.btn:disabled:hover { background: transparent; color: var(--ink); }

.btn-primary { background: var(--stamp-red); border-color: var(--stamp-red); color: #fff; }
.btn-primary:hover { background: var(--redact-black); border-color: var(--redact-black); color: #fff; }
.btn-primary:disabled:hover { background: var(--stamp-red); border-color: var(--stamp-red); }

.btn-quiet { border-color: var(--ink-soft); color: var(--ink-soft); }
.btn-quiet:hover { background: transparent; border-color: var(--redact-black); color: var(--ink); }

.hint {
  max-width: var(--prose);
  margin: .9rem 0 0;
  font-size: .82rem;
  color: var(--ink-soft);
}

/* ---------- board ---------- */

.board {
  padding: clamp(1.5rem, 3vw, 2rem) var(--gutter) clamp(3rem, 6vw, 5rem);
  padding-left: max(var(--gutter), env(safe-area-inset-left));
  padding-right: max(var(--gutter), env(safe-area-inset-right));
  border-top: 2px solid var(--redact-black);
}

.board-intro {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: .5rem 3rem;
  margin-bottom: clamp(1.25rem, 3vw, 2rem);
}

.board-title {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(1.35rem, 1rem + 1.4vw, 2rem);
  font-weight: 400;
}

.board-note {
  /*flex: 0 1 34rem;*/
  margin: 0;
  font-size: .85rem;
  max-width: 150ch;
  color: var(--ink-soft);
}

.board-cols { display: none; }

.board-list { margin: 0; padding: 0; list-style: none; }

/* Stacked cards below 769px — five columns at 375px is unreadable. */
.board-row {
  display: grid;
  grid-template-columns: 1.9rem minmax(0, 1fr);
  gap: .35rem .9rem;
  padding: 1.1rem 0;
  border-top: 1px solid var(--ink-soft);
}

.board-rank {
  font-family: var(--mono);
  font-size: .8rem;
  color: var(--ink-soft);
  padding-top: .15rem;
}

.row-label {
  display: block;
  margin-bottom: .2rem;
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  font-style: normal;
  color: var(--ink-soft);
}

.board-said { margin: 0; font-style: italic; color: var(--ink-soft); }

/* Red, and sized UP to earn it. stamp-red is 4.3:1 on paper: AA for large text
   only, meaning 24px, or 18.66px when bold. At the previous 1.05rem/16.8px bold
   this colour would have failed the contrast bar on the most-read text in the
   section. 1.2rem is 19.2px, which clears it. */
.board-meant {
  grid-column: 2;
  margin: 0;
  font-size: 1.2rem;
  font-weight: 600;
  line-height: 1.3;
}

/* Starter rows already sit at reduced opacity; keep their red from competing
   with the real entries above them. */
.board-row-starter .board-meant { color: var(--ink); }

.board-stats {
  grid-column: 2;
  display: flex;
  gap: 1.25rem;
  margin: 0;
  font-family: var(--mono);
  font-size: .78rem;
  color: var(--ink-soft);
}

@media (min-width: 769px) {
  .board-cols,
  .board-row {
    display: grid;
    grid-template-columns: 2.5rem minmax(0, 1fr) minmax(0, 1.15fr) 5rem 6rem;
    gap: 0 clamp(1rem, 2vw, 2.5rem);
    align-items: baseline;
  }

  .board-cols {
    padding-bottom: .7rem;
    font-family: var(--mono);
    font-size: .75rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--ink-soft);
  }

  .board-cols .num { text-align: right; }
  .board-meant { grid-column: auto; }
  .board-stats { display: contents; }

  .board-stats .stat {
    font-family: var(--mono);
    font-size: .85rem;
    text-align: right;
    color: var(--ink);
  }

  .stat-label,
  .row-label { display: none; }
}

/* Below the two-column breakpoint the "people" column has no heading, so the
   stacked row carries its own labels. */
.stat-label { color: var(--ink-soft); }

.board-empty {
  padding: 1.1rem 0;
  border-top: 1px solid var(--ink-soft);
  color: var(--ink-soft);
  font-size: .92rem;
}

/* ---------- footer ---------- */

.site-footer {
  border-top: 2px solid var(--redact-black);
  padding: .9rem var(--gutter);
  padding-bottom: max(.9rem, env(safe-area-inset-bottom));
  padding-left: max(var(--gutter), env(safe-area-inset-left));
  padding-right: max(var(--gutter), env(safe-area-inset-right));
}

.footer-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .5rem 1.25rem;
}

/* Baseline, not centre. The wordmark is Special Elite and the pill is Plex Mono:
   two faces with different x-heights, so centring their BOXES leaves their text
   visibly off from each other. Aligning the baselines is what the eye reads. */
.footer-brand { display: flex; align-items: baseline; gap: .6rem; }

.footer-wordmark {
  font-family: var(--display);
  font-size: .85rem;
  letter-spacing: .04em;
}

/* One rule for every place MEANT is picked out in red: masthead, board column
   header, footer. These were three separate inline colour declarations, which
   quietly turned a locked palette into a four-file edit. No tilt here -- at
   .85rem a rotated word fights the baseline the footer is aligned to. */
.accent { color: var(--stamp-red); }

.version-pill {
  padding: .1rem .5rem;
  border: 1px solid var(--ink-soft);
  font-family: var(--mono);
  font-size: .72rem;
  color: var(--ink-soft);
}

.footer-links { display: flex; flex-wrap: wrap; align-items: center; gap: .25rem 1.25rem; }

.text-link {
  font-family: var(--mono);
  font-size: .78rem;
  color: var(--accent-olive);
  background: none;
  border: 0;
  cursor: pointer;
  text-decoration: none;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

.text-link:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ---------- dialogs ---------- */

.sheet {
  width: min(36rem, calc(100vw - 2rem));
  padding: clamp(1.25rem, 4vw, 2rem);
  border: 2px solid var(--redact-black);
  background: var(--paper-dark);
  color: var(--ink);
}

.sheet::backdrop { background: rgb(0 0 0 / .7); }

.sheet h2 {
  margin: 0 0 1rem;
  font-family: var(--display);
  font-size: 1.3rem;
  font-weight: 400;
}

.sheet p { margin: 0 0 .9rem; font-size: .92rem; }

.sheet-note {
  padding-top: .9rem;
  border-top: 1px solid var(--ink-soft);
  font-family: var(--mono);
  font-size: .78rem;
  color: var(--ink-soft);
}

.sheet .btn { margin-top: .5rem; }

@media (prefers-reduced-motion: reduce) {
  /* Fall back to a plain cross-fade: no wipe, no bounce, no shimmer. */
  .result[data-state="revealing"] .meant,
  .result[data-state="revealing"] .savage { visibility: visible; }

  .result[data-state="loading"]::after { display: none; }

  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ---------- example chips ----------
   A first-time visitor often has no message to hand. These give them one, and
   they double as the fastest way to show what the product finds funny. */

.examples { margin-top: 1.5rem; }

.examples-label {
  display: block;
  margin-bottom: .55rem;
  font-family: var(--mono);
  font-size: .75rem;
  color: var(--ink-soft);
}

.examples-row {
  display: flex;
  gap: .5rem;
  flex-wrap: wrap;
}

/* Below the two-column breakpoint these scroll sideways rather than becoming a
   six-item vertical list that pushes the input off screen. */
@media (max-width: 768px) {
  .examples-row {
    flex-wrap: nowrap;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    /* Bleed to the viewport edge so the row reads as scrollable. */
    margin-inline: calc(-1 * var(--gutter));
    padding-inline: var(--gutter);
    padding-bottom: .35rem;
  }
  .examples-row::-webkit-scrollbar { display: none; }
  .chip { scroll-snap-align: start; }
}

.chip {
  flex: none;
  min-height: 36px;
  padding: .4rem .75rem;
  background: var(--paper-dark);
  color: var(--ink);
  border: 1px solid var(--ink-soft);
  border-radius: 0;
  font-family: var(--sans);
  font-size: .82rem;
  font-style: italic;
  white-space: nowrap;
  cursor: pointer;
  transition: background .12s ease-out, border-color .12s ease-out;
}

.chip:hover {
  background: var(--paper);
  border-color: var(--redact-black);
}

.chip:active { background: var(--stamp-red); color: #fff; border-color: var(--stamp-red); }

/* ---------- empty state ---------- */

.empty { max-width: 34ch; }

.empty-lead {
  margin: 0;
  font-size: 1.05rem;
  color: var(--ink-soft);
}

.empty-example {
  margin: 1.25rem 0 0;
  padding-top: 1.25rem;
  border-top: 1px solid var(--ink-soft);
  font-style: italic;
  font-size: 1.15rem;
  color: var(--ink);
  transition: opacity .35s ease-out;
}

.empty-example[data-fading="true"] { opacity: 0; }

/* Mobile: the brief's hierarchy is textarea, then count, then a full-width
   button. Side by side works on desktop where the row is wide; at 390px it
   leaves the primary action looking optional. */
@media (max-width: 768px) {
  .field-foot {
    flex-direction: column;
    align-items: stretch;
    gap: .6rem;
  }
  .count { order: -1; text-align: right; }
  .decode { max-width: none; width: 100%; min-height: 52px; }
}

/* ---------- toast ----------
   Desktop share is two separate actions (file downloads, link goes to the
   clipboard) and neither announces itself, so something has to. */

.toast {
  position: fixed;
  left: 50%;
  bottom: max(1.25rem, env(safe-area-inset-bottom));
  z-index: 10;
  transform: translate(-50%, 1rem);
  padding: .7rem 1.1rem;
  background: var(--redact-black);
  color: var(--paper);
  border: 0;
  font-family: var(--mono);
  font-size: .8rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease-out, transform .2s ease-out;
}

.toast[data-visible="true"] {
  opacity: 1;
  transform: translate(-50%, 0);
}

@media (prefers-reduced-motion: reduce) {
  .toast { transition: opacity .01ms; }
}

/* Starter rows: seeded phrases filling the board until real ones overtake them.
   Held back visually so the eye reads the filed entries first, and their count
   renders as a dash rather than an invented number. */
.board-row-starter .board-said,
.board-row-starter .board-meant,
.board-row-starter .stat { opacity: .72; }

/* Narrow panel: the 9rem label column leaves ten cells about 7px wide each, which
   is a texture rather than a reading. Label and number take one row, the cells
   take the full width beneath. Container query, same as the stamp: this depends
   on the panel, not the window. */
@container (max-width: 26rem) {
  .meter {
    grid-template-columns: 1fr auto;
    gap: .3rem .75rem;
  }
  .meter-name { grid-column: 1; grid-row: 1; }
  .meter-num { grid-column: 2; grid-row: 1; }
  .meter-cells { grid-column: 1 / -1; grid-row: 2; }
}

.sheet h3 {
  margin: 1.5rem 0 .6rem;
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 400;
}
