/* The participant chrome: ground, voices, identity block.
 *
 * Shared by every page a participant meets — the entrance (/), the join sheet
 * (/join/<code>), the identity step (/identity/<code>), the survey itself and
 * the debrief (/thanks) — so the walk from a QR code to the withdrawal link
 * looks like one place rather than five. The survey and debrief joined on
 * 27 August 2026; before that they still wore the old teal Bootstrap bar, and
 * the pages a participant spent the most time on were the two that did not
 * look like the tool they were in.
 *
 * This file holds ONLY what those pages have in common. Page-specific rules
 * live beside it (home.css). It is CG's own: static/css/share-card.css is a
 * FLEET-SHARED file, byte-identical in eight tools and checked by
 * server-ops/sync_shared_assets.py, so nothing here may edit it — the join
 * sheet keeps the fleet card and simply stands on CG's ground.
 *
 * In a stylesheet rather than a <style> block or style= attributes: these pages
 * are the wrong place to add to FL-020's pile.
 */

:root {
  --cg-ground: #F6F8FB;
  --cg-ink: #092C6D;
  --cg-muted: #5A6B84;
  --cg-line: #DCE3EC;
  --cg-cyan: #14BFC3;
}

/* These files are linked ONLY from participant pages, so bare element selectors
   are safe here and no marker class on <body> is needed. */
body {
  background: var(--cg-ground);
  color: var(--cg-ink);
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

/* base.html wraps each page's block in <main id="main">; it has to become a
   flex child so the stage can fill the space between header and footer. */
#main { flex: 1; display: flex; }

.cg-stage {
  flex: 1;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2.5rem 1.5rem;
  overflow: hidden;
}
/* The longer pages start at the top instead of centring: a form taller than the
   viewport would otherwise have its first field pushed off the screen. */
.cg-stage--top { align-items: flex-start; }

/* The voices live here, behind everything, injected by voices.js. Absolutely
   positioned so nothing the motion does can move the primary action.

   THE LAYER IS ONE SCREEN TALL AT MOST (20 September 2026). It used to be
   `inset: 0`, which on a phone made it as tall as the whole DOCUMENT — so
   opening "How to complete this survey" grew it from 784 px to 1,212 px and
   restaged the entire composition while the panel animated: the voices sit at
   fractions of the height, and the lowest pair slid four hundred pixels in
   about a third of a second. Capped at one viewport, content growing below the
   fold no longer touches the picture. `svh` and not `vh` or `dvh`: the SMALL
   viewport height is the one that does not change when the mobile URL bar
   slides away, and a background that restages itself on a scroll gesture is
   the same defect in a different coat. Where the stage is shorter than a
   screen — the thank-you page, the code field — `height: 100%` still wins and
   nothing changes. */
.cg-voices {
  position: absolute; inset: 0 0 auto 0; z-index: 0;
  height: 100%;
  max-height: 100vh;
  max-height: 100svh;
}

/* Clears the middle so content never has to compete with a bubble that happens
   to drift behind it. Radial rather than linear because these compositions are
   centred and have no left or right — which is also what makes them mirror
   under dir="rtl" without changes (FL-030, Decision 2). */
/* The veil covers exactly what the voices cover, so the two are capped
   together — a bright centre sitting at the middle of a 1,200 px document
   lights up nothing the reader is looking at. */
.cg-veil {
  position: absolute; inset: 0 0 auto 0; z-index: 1; pointer-events: none;
  height: 100%;
  max-height: 100vh;
  max-height: 100svh;
  background: radial-gradient(ellipse 46% 52% at 50% 50%,
    rgba(246,248,251,.97) 0%, rgba(246,248,251,.93) 42%,
    rgba(246,248,251,.55) 72%, rgba(246,248,251,0) 100%);
}
/* Where a solid card carries the content, the veil only has to keep the edges
   calm — the card itself does the rest. */
.cg-veil--soft {
  background: radial-gradient(ellipse 60% 62% at 50% 46%,
    rgba(246,248,251,.92) 0%, rgba(246,248,251,.78) 48%,
    rgba(246,248,251,.34) 76%, rgba(246,248,251,0) 100%);
}

/* Content that sits on the stage: above the veil, and centred with a sane
   maximum so a form does not run to the window edge. */
.cg-page {
  position: relative; z-index: 2;
  width: 100%; display: flex; flex-direction: column;
  align-items: center; gap: 1.5rem;
}
.cg-stage > .share-page { position: relative; z-index: 2; width: 100%; }

.cg-inner {
  position: relative; z-index: 2;
  width: 100%; max-width: 41rem;
  text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 1.4rem;
}

/* Identity: the mark plus the name. The asset is 434x324, so a 92px width is
   69px tall — the width/height attributes in the templates say so, which keeps
   the line from jumping while the SVG loads. The mark carries no wordmark of
   its own, unlike the other tools' lockups, so the name is set beside it here:
   selectable, translatable, and legible at any size. */
.cg-brand { display: flex; flex-direction: column; align-items: center; gap: .55rem; }
.cg-mark { display: block; width: 92px; height: auto; }
.cg-wordmark {
  margin: 0; font-size: .95rem; font-weight: 700;
  letter-spacing: .13em; text-transform: uppercase; color: var(--cg-ink);
}
.cg-brand--small .cg-mark { width: 64px; }
.cg-brand--small .cg-wordmark { font-size: .8rem; letter-spacing: .12em; }

@media (max-width: 720px) {
  .cg-stage { padding: 1.6rem 1.15rem 2rem; }
  .cg-page { gap: 1.1rem; }
  .cg-entry { max-width: none; }
  .cg-inner { gap: 1.05rem; max-width: none; }
  .cg-mark { width: 76px; }
  .cg-wordmark { font-size: .85rem; letter-spacing: .11em; }
  /* Wider and shallower: on a phone the copy runs the full width, so the clear
     area has to be a band across the middle rather than a disc in it. */
  .cg-veil {
    background: radial-gradient(ellipse 88% 56% at 50% 50%,
      rgba(246,248,251,.98) 0%, rgba(246,248,251,.95) 52%,
      rgba(246,248,251,.62) 80%, rgba(246,248,251,0) 100%);
  }
  .cg-veil--soft {
    background: radial-gradient(ellipse 96% 64% at 50% 46%,
      rgba(246,248,251,.94) 0%, rgba(246,248,251,.84) 54%,
      rgba(246,248,251,.4) 82%, rgba(246,248,251,0) 100%);
  }
}

/* The code-entry form. Shared by the entrance and /enter-code since the
   Start button moved the code off the first page (17 August 2026). */
.cg-entry {
  width: 100%; max-width: 20rem;
  display: flex; flex-direction: column; gap: .6rem; margin: .2rem 0 0;
}
.cg-entry label {
  font-size: .78rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--cg-muted); text-align: center;
}
.cg-code {
  width: 100%; height: 56px;
  border: 2px solid var(--cg-line); border-radius: 10px; background: #fff;
  text-align: center; font-size: 1.5rem; font-weight: 700;
  letter-spacing: .34em; text-indent: .34em; color: var(--cg-ink);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.cg-code::placeholder { color: #B8C4D4; font-weight: 600; letter-spacing: .34em; }
.cg-code:focus {
  outline: none; border-color: var(--cg-cyan);
  box-shadow: 0 0 0 4px rgba(20,191,195,.18);
}

.cg-go {
  height: 52px; border: 0; border-radius: 10px;
  background: var(--cg-ink); color: #fff;
  font-size: 1.02rem; font-weight: 700; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.cg-go:hover { background: #0B3B8C; }
.cg-go:active { transform: translateY(1px); }
/* The entrance's Start is a link, not a submit: there is nothing to post. */
.cg-go--link { text-decoration: none; min-width: 13rem; padding: 0 2rem; }
.cg-code:focus-visible, .cg-go:focus-visible {
  outline: 3px solid var(--cg-cyan); outline-offset: 3px; border-radius: 6px;
}

.cg-error { color: #B3261E; font-size: .88rem; margin: 0; min-height: 1.2em; }
.cg-notice { color: #1E5E3A; background: #E8F4EC; border-radius: 6px; padding: .55rem .8rem; font-size: .9rem; margin: 0 0 .8rem; }


/* ── the entrance and the code step ───────────────────────────────────────
   Merged from home.css on 17 August 2026, when the code moved to its own
   page: the two pages share the mark, the heading, the lede, the field and
   the button, and a file called home.css linked from /enter-code would be a
   lie about where its rules apply. */
.cg-proposition {
  font-size: clamp(1.85rem, 4.6vw, 2.85rem);
  line-height: 1.12; letter-spacing: -.022em; font-weight: 800;
  text-wrap: balance; max-width: 18ch; margin: 0;
}

.cg-proposition--sm { font-size: clamp(1.5rem, 3.2vw, 2.1rem); }

.cg-lede {
  color: var(--cg-muted); font-size: 1.02rem; line-height: 1.62;
  max-width: 34rem; margin: 0;
}
.cg-lede strong { color: var(--cg-ink); font-weight: 650; }

.cg-meta { font-size: .85rem; color: var(--cg-muted); margin: 0; }
.cg-edu { font-size: .86rem; margin: 0; }
.cg-edu a { color: var(--cg-muted); text-decoration: none; }
.cg-edu a:hover { color: var(--cg-ink); text-decoration: underline; }

.cg-edu a:focus-visible {
  outline: 3px solid var(--cg-cyan); outline-offset: 3px; border-radius: 6px;
}

@media (max-width: 720px) {
  .cg-proposition { max-width: none; }
  .cg-lede { font-size: .96rem; }
}

/* ── the survey and the debrief ───────────────────────────────────────────
   Joined the chrome on 27 August 2026 (visual only — no field, id, wording or
   behaviour changed; the consent copy is versioned under FL-004 and stayed
   byte-identical). These two pages keep their Bootstrap widget markup — the
   collapse, the cards, the button classes the survey script generates — so
   everything below either styles a cg-* class the templates now carry, or
   re-colours a Bootstrap class inside the .cg-flow scope. Re-colouring in CSS
   rather than renaming classes in JS keeps the survey script untouched: it
   builds the DOM and must go on finding what it built. */

/* The panel: what used to be a teal `alert` with white text. Ink on the
   chrome's white, with the mark's cyan standing where the teal was. */
.cg-panel {
  background: #fff;
  border: 1px solid var(--cg-line);
  border-inline-start: 4px solid var(--cg-cyan);
  border-radius: 10px;
  padding: .95rem 1.15rem;
  color: var(--cg-ink);
  text-align: start;
}
.cg-panel--success { border-inline-start-color: #2E9E63; }
.cg-panel--success h3 { font-size: 1.3rem; font-weight: 800; color: var(--cg-ink); }

/* The collapse toggle inside the help panel. Its old `btn-outline-light` was
   drawn for the teal ground and disappears on white. */
.cg-panel__toggle {
  border: 1px solid var(--cg-line);
  color: var(--cg-muted);
  background: transparent;
  white-space: nowrap;   /* "▶ Show" is one gesture, not an icon over a word */
  flex-shrink: 0;
}
.cg-panel__toggle:hover { background: var(--cg-ground); color: var(--cg-ink); border-color: var(--cg-line); }
/* The ▼/▶ labels follow the button's own aria-expanded, which Bootstrap
   maintains — the old inline display:none meant "Hide" never appeared. */
/* Both labels occupy the SAME grid cell, so the button is always as wide as
   the wider of them and the swap moves nothing. They used to be shown and
   hidden with `display`, which made the button change width — and on a phone
   that was enough to wrap "How to complete this survey" onto a second line
   while collapsed and unwrap it on opening. The header jumped 17px every time
   the panel was opened or closed, which is the flicker the owner reported on
   20 September 2026. `visibility` also keeps the inactive label out of the
   accessibility tree, which `display: none` did too. */
.cg-panel__toggle { display: inline-grid; align-items: center; }
.cg-panel__toggle > span { grid-area: 1 / 1; }
.cg-panel__toggle[aria-expanded="true"] .when-collapsed { visibility: hidden; }
.cg-panel__toggle[aria-expanded="false"] .when-expanded { visibility: hidden; }
.cg-panel__inset { margin-inline-start: 20px; margin-top: 12px; }

/* The debrief's content column: the old w-sm-75/w-md-50 utilities are not in
   this Bootstrap build, so the column was only ever shaped by its content. */
.cg-sheet { width: 100%; max-width: 44rem; text-align: start; }

/* Scroll anchoring keeps whatever was at the top of the viewport in place as
   the page grows. On the survey that is the wrong instinct: each statement
   REPLACES the last, and the new one is often taller, so anchoring quietly
   dragged the participant towards the bottom of the page instead of leaving
   them at the statement they had just been given (owner, 20 September 2026).
   The step change does its own scrolling; nothing here should second-guess it. */
#form-start-quiz, #form-start-quiz * { overflow-anchor: none; }

/* The survey form: same fix, stated instead of inherited. */
.cg-flow #form-quiz { width: 100%; max-width: 46rem; }

/* The help panel sits over the form, so it takes the form's measure rather
   than Bootstrap's container widths. The explicit width matters: these are
   children of .cg-page, a centred flex column, and a centred flex child sizes
   to max-content — on a phone that is wider than the screen, and body's
   overflow-x:clip then cuts the right edge off instead of scrolling to it. */
.cg-flow .container,
.cg-flow .main { width: 100%; }
.cg-flow .container { max-width: 46rem; }

/* Bootstrap re-coloured inside the flow: navy where the framework said green
   or blue, the cyan ring where it said blue. No sizes change here. */
.cg-flow .btn-success {
  background: var(--cg-ink);
  border-color: var(--cg-ink);
}
.cg-flow .btn-success:hover,
.cg-flow .btn-success:focus { background: #0B3B8C; border-color: #0B3B8C; }
.cg-flow .btn-success:disabled { background: #93A5C4; border-color: #93A5C4; }
.cg-flow .btn-outline-primary { color: var(--cg-ink); border-color: var(--cg-ink); }
.cg-flow .btn-outline-primary:hover { background: var(--cg-ink); border-color: var(--cg-ink); color: #fff; }
.cg-flow .btn-outline-secondary { color: var(--cg-muted); border-color: var(--cg-line); }
.cg-flow .btn-outline-secondary:hover { background: var(--cg-ground); color: var(--cg-ink); border-color: var(--cg-line); }
.cg-flow .form-check-input:checked { background-color: var(--cg-ink); border-color: var(--cg-ink); }
.cg-flow .form-check-input:focus {
  border-color: var(--cg-cyan);
  box-shadow: 0 0 0 .25rem rgba(20, 191, 195, .25);
}
/* The comfort scale's pressed state (btn-check + label). */
.cg-flow .btn-check:checked + .btn-outline-secondary {
  background: var(--cg-ink);
  border-color: var(--cg-ink);
  color: #fff;
}
.cg-flow .btn-check:focus + .btn-outline-secondary {
  box-shadow: 0 0 0 .25rem rgba(20, 191, 195, .25);
}

/* Touch devices get touch-sized controls. Participants meet the survey on
   their phones almost every time (it is joined from a QR code in a classroom),
   and Bootstrap's 1em radio is a precision target. 1.5em ≈ 24px plus the
   label's own hit area; the answer rows are spaced so neighbouring values
   cannot be fat-fingered. Gated on pointer:coarse rather than width — a small
   window on a laptop still has a mouse. */
@media (pointer: coarse) {
  .cg-flow .form-check-input {
    width: 1.5em;
    height: 1.5em;
    margin-top: .125em;
  }
  .cg-flow .form-check { min-height: 2em; margin-bottom: .35rem; }
  .cg-flow .form-check-label { padding-inline-start: .15rem; padding-block: .15rem; }
  /* The comfort scale's five steps: tall enough to be five separate targets. */
  .cg-flow .btn-group .btn-sm { padding: .45rem .8rem; font-size: .95rem; }
}

/* The debrief's cards keep their Bootstrap class; only the paint changes. The
   withdrawal card keeps its amber edge — it is the one thing on the page that
   must not read as routine. */
.cg-flow .card { border-color: var(--cg-line); border-radius: 10px; }
.cg-flow .card.border-warning {
  border-color: #E4B04A;
  border-inline-start: 4px solid #E4B04A;
}

/* The join sheet is made to be printed and handed out. Ink on paper should be
   the card, not the background. */
@media print {
  .cg-voices, .cg-veil { display: none !important; }
  body { background: #fff; }
}

/* ── the educator's sign-in ──────────────────────────────────────────────────
   The entrance composition with a form in it (27 August 2026). It reuses the
   entrance's ground, veil, mark, heading and .cg-go button; only the two
   text fields are new, because .cg-code is a six-character code box with
   .34em of letterspacing and would be absurd for an e-mail address. */
.cg-signin {
  width: 100%; max-width: 22rem;
  display: flex; flex-direction: column; gap: .9rem;
  margin: .2rem 0 0;
  text-align: start;
}
.cg-signin__field { display: flex; flex-direction: column; gap: .3rem; }
.cg-signin__field label {
  font-size: .78rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--cg-muted);
}
.cg-signin__field input {
  width: 100%; height: 46px; box-sizing: border-box;
  padding: 0 .8rem;
  border: 2px solid var(--cg-line); border-radius: 10px; background: #fff;
  font: inherit; font-size: 1rem; color: var(--cg-ink);
}
.cg-signin__field input:focus {
  outline: none; border-color: var(--cg-cyan);
  box-shadow: 0 0 0 4px rgba(20, 191, 195, .18);
}
.cg-signin .cg-go { margin-top: .3rem; }
/* "Sign in with a passkey" (FL-065, 2 October 2026): the sign-in column's
   width, so its button lines up with "Log in". No display rule here, so the
   `hidden` attribute it starts with keeps working. */
.cg-passkey { width: 100%; max-width: 22rem; }
.cg-passkey .cg-meta { text-align: center; }
/* The lockup is a link on the sign-in page (back to the entrance); it must not
   pick up an underline from the browser default. */
a.cg-brand { text-decoration: none; color: inherit; }
a.cg-brand:focus-visible { outline: 3px solid var(--cg-cyan); outline-offset: 4px; border-radius: 8px; }
