/* Gamma Lab — one board, one slider. Deliberately quiet: the only thing on this page that should
   pull the eye is the bar chart and the sign of the number above it.

   RESPONSIVE (gamma-lab-mobile.md, GLM-001). Three width classes plus a short-height class:

     compact   <= 599px      phone portrait
     medium    600-1023px    phone landscape, tablet portrait
     regular   >= 1024px     tablet landscape, desktop
     short     height <= 500px   applies ON TOP of the width class

   Touch affordances are keyed on `any-pointer: coarse`, NOT on width and NOT on `pointer: coarse`
   (GLM-002): a touch laptop reports a FINE primary pointer while still having a touchscreen, so
   `pointer: coarse` would leave its 26px zoom buttons unfixed. Width decides layout; `any-pointer`
   decides target size; `pointer` decides input behaviour (see the keyboard-dismiss in the JS).

   Every size that carries text is in `rem` (GLM-046). The page used to declare every font in px,
   which meant a reader's text-size preference did nothing at all. */
:root {
  --gl-bg: #080b10;
  --gl-panel: #0f141c;
  --gl-line: #1e2632;
  --gl-line-2: #2b3644;
  --gl-ink: #f2f6fb;
  --gl-ink-2: #93a2b4;
  /* small text sits on --gl-panel at 10-12px; #5d6b7c measured below AA there */
  --gl-ink-3: #8fa0b3;
  --gl-pos: #3987e5;
  --gl-pos-glow: #7fb6ff;
  --gl-neg: #e66767;
  --gl-neg-glow: #ff9b9b;
  --gl-spot: #ffd23f;
  --gl-warn: #fab219;
  /* A frozen board is a STATE, not a warning: cool and calm, deliberately not the amber that
     means "this number may be wrong". Measured at 7.9:1 on --gl-panel. */
  --gl-frozen: #7fb6ff;
  --gl-ink-4: #64707e;   /* decorative only — never text that must be read */
  --gl-mono: ui-monospace, "SF Mono", Menlo, "Cascadia Mono", monospace;

  /* The table box height. A CONSTANT per breakpoint — never a max-height, never content-driven.
     See .gl-tablewrap for why that is load-bearing. */
  --gl-table-h: 320px;
  /* The chart height. Overridden per class below; `svh` deliberately, never `dvh` (GLM-031). */
  --gl-canvas-h: 400px;
}

body {
  margin: 0;
  background: var(--gl-bg);
  color: var(--gl-ink);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  /* iOS Safari otherwise inflates text on orientation change, which breaks a layout tuned at a
     known font size. This does NOT disable deliberate user text zoom (GLM-042). */
  -webkit-text-size-adjust: 100%;
}

/* Visually hidden but STILL IN THE ACCESSIBILITY TREE (GLM-047's note, GLM-045).
   `display: none` would take the content from a screen reader too. None of the five properties
   that break this pattern — display:none, visibility:hidden, content-visibility:hidden, opacity:0,
   aria-hidden — may ever be added here; the layout test asserts their absence. */
.gl-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.gl-wrap {
  max-width: 1120px;
  margin: 0 auto;
  padding: 16px 16px 40px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* THE DETACHED AUTH CHIP OVERLAPS THIS PAGE, so this page reserves room for it.
 *
 * option-chain-auth.css pins the "Signed in as … / Sign out" chip with `position: fixed; top: 8px;
 * right: 10px` and reserves no space for it. Where a nav rail exists the BAR adopts the chip
 * (`.oc-topnav #oc-auth-bar`) and it costs the page nothing — but the public Gamma Lab has no rail
 * (PGL-006), so the chip stays a direct child of <body> and floats over whatever is at the top of
 * the document. That is `.gl-top`: measured on a signed-in iPhone 16, the chip painted straight
 * across the symbol input, the Load button and the board-time line.
 *
 * THE CLASS IS APPLIED BY JAVASCRIPT, and it must be. This was first written as
 * `body:has(> #oc-auth-bar) .gl-wrap`, which is the more elegant rule and works in Chromium — but
 * option-chain-auth.js appends the chip AFTER load, and WebKit does not restyle for that. Measured
 * on iOS 26.5: `CSS.supports('selector(body:has(> #oc-auth-bar))')` is true AND
 * `querySelector('body:has(> #oc-auth-bar)')` finds the element, yet the computed padding-top stays
 * 12px. Safari matches the selector without invalidating the style, so the reserve never applied on
 * the one surface that needs it. A class toggled from gamma-lab.js does not depend on that.
 *
 * Not width-scoped: `.gl-top` is `space-between`, so the board-time line sits hard right at every
 * width, which is exactly where the chip is. 46px clears a chip whose height is driven by its
 * logout button (~34.4px) sitting at y=8.
 */
.gl-wrap.gl-auth-chip { padding-top: 46px; }

.gl-top { display: flex; justify-content: space-between; align-items: center; gap: 14px; flex-wrap: wrap; }
.gl-sym { display: flex; gap: 8px; }
.gl-input {
  font-family: var(--gl-mono);
  /* NEVER below 16px computed: iOS Safari zooms the viewport on focus below that and does not zoom
     back. max() keeps the floor even if the reader's root size is smaller than the default. */
  font-size: max(1rem, 16px);
  text-transform: uppercase;
  width: 8rem;
  min-width: 0;
  box-sizing: border-box;
  padding: 7px 10px;
  color: var(--gl-ink);
  background: var(--gl-panel);
  border: 1px solid var(--gl-line-2);
  border-radius: 7px;
}
.gl-btn {
  font: inherit;
  font-size: 0.8125rem;
  box-sizing: border-box;
  padding: 7px 14px;
  color: var(--gl-ink-2);
  background: var(--gl-panel);
  border: 1px solid var(--gl-line-2);
  border-radius: 7px;
  cursor: pointer;
}
/* Hover only where a pointer can actually hover (GLM-041). On touch an unconditional :hover sticks
   to the last-tapped control, so the page shows something as "pointed at" when nothing is.
   :focus-visible is deliberately NOT moved — keyboard focus is orthogonal to pointer type. */
@media (hover: hover) {
  .gl-btn:hover { color: var(--gl-ink); border-color: var(--gl-ink-3); }
}
.gl-input:focus-visible, .gl-btn:focus-visible, #glSlider:focus-visible {
  outline: 2px solid var(--gl-spot);
  outline-offset: 2px;
}
.gl-asof { font-size: 0.75rem; color: var(--gl-ink-3); }
.gl-lb-link { font-size: 0.8rem; color: var(--gl-ink-2, #8b97ad); text-decoration: none;
              margin-left: 12px; white-space: nowrap; }
/* GLM-041: hover styling only where hovering exists — on touch, :hover sticks after a tap. */
@media (hover: hover) {
  .gl-lb-link:hover { color: var(--gl-ink-1, #dfe6f2); }
}

.gl-hud { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; }
.gl-r { background: var(--gl-panel); border: 1px solid var(--gl-line); border-radius: 8px; padding: 10px 13px; min-width: 0; }
.gl-k { font-size: 0.625rem; letter-spacing: .13em; text-transform: uppercase; color: var(--gl-ink-3); }
.gl-v {
  font-family: var(--gl-mono);
  font-variant-numeric: tabular-nums;
  font-size: 1.5625rem;
  font-weight: 600;
  letter-spacing: -.02em;
  margin-top: 2px;
  line-height: 1.1;
  /* No font size can guarantee an arbitrary value fits, so the contract is NEVER OVERFLOWS, not
     always-one-line: a longer value wraps inside its tile rather than escaping it (GLM-037). */
  overflow-wrap: anywhere;
}
/*
 * The Regime value carries more words than the numeric readouts beside it, so it sets its own size
 * rather than inheriting .gl-v's. This was a style="font-size:19px" attribute inside the HUD's
 * innerHTML string; it moved here so the public surface can enforce `style-src 'self'` — a style
 * attribute in parsed markup is blocked outright without 'unsafe-inline'.
 */
.gl-v-regime { font-size: 1.1875rem; }

.gl-v.pos { color: var(--gl-pos-glow); }
.gl-v.neg { color: var(--gl-neg-glow); }
.gl-v.spot { color: var(--gl-spot); }
.gl-sub { font-size: 0.6875rem; color: var(--gl-ink-2); margin-top: 3px; }
.gl-stale { color: var(--gl-warn); font-weight: 600; }

/* ---------------------------------------------------------------- the stage
 *
 * STRUCTURE (GLM-010). Nothing overlays the canvas any more:
 *
 *   .gl-stage          the panel. No role, not focusable.
 *     .gl-stage-head   flex row — .gl-range (flex 1, ellipsis) | .gl-zoom (flex none)
 *     .gl-plot         role=application, tabindex=0, touch-action: pan-y. THE gesture surface.
 *         canvas       aria-hidden
 *     .gl-legend       the key, BELOW the chart it explains
 *
 * The range readout and the zoom cluster used to be `position: absolute` inside the stage, which
 * put them in the CANVAS's coordinate space — and the canvas draws its own spot-price label into
 * the same band. A DOM overlay and a canvas drawing cannot arbitrate; the only fix is to stop
 * sharing the space. This also makes the legend-over-buttons collision impossible (a flex row's
 * children cannot overlap), and takes the zoom buttons OUT of the pan surface, so a pointerdown on
 * "−" can no longer bubble into the chart's drag handler.
 */
.gl-stage {
  background: var(--gl-panel);
  border: 1px solid var(--gl-line);
  border-radius: 10px;
  padding: 10px 10px 4px;
}
.gl-stage-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}

/* The pan/zoom surface, and nothing else. `pan-y` is what lets a vertical swipe scroll the PAGE
   while horizontal and multi-touch gestures stay ours (GLM-020) — the old `touch-action: none`
   meant a swipe over half the viewport did nothing at all. It also suppresses the browser's own
   pinch-zoom here, so the page's pinch handler has no competitor. */
.gl-plot {
  position: relative;
  cursor: grab;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
}
.gl-plot.gl-grabbing { cursor: grabbing; }
.gl-plot:focus-visible { outline: 2px solid var(--gl-spot); outline-offset: 2px; }

#glCanvas {
  display: block;
  width: 100%;
  height: var(--gl-canvas-h);
  border-radius: 6px;
}

/* What the window is showing — the reader should never have to guess whether they are looking
   at the whole board or a slice of it. Ellipsis, never wrap: the head is a fixed-height row and a
   wrapped readout would push the canvas down. */
.gl-range {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--gl-mono);
  font-size: 0.65625rem;
  color: var(--gl-ink-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.gl-zoom { flex: 0 0 auto; display: flex; gap: 5px; }
.gl-zb {
  font: inherit;
  font-size: 0.8125rem;
  line-height: 1;
  min-width: 26px;
  box-sizing: border-box;
  padding: 4px 6px;
  color: var(--gl-ink-2);
  background: var(--gl-bg);
  border: 1px solid var(--gl-line-2);
  border-radius: 6px;
  cursor: pointer;
}
@media (hover: hover) {
  .gl-zb:hover { color: var(--gl-ink); border-color: var(--gl-ink-3); }
}
.gl-zb:focus-visible { outline: 2px solid var(--gl-spot); outline-offset: 2px; }
.gl-zb-wide { min-width: auto; font-size: 0.6875rem; letter-spacing: .04em; }

/* The chart's key, under the chart it explains. It is the ONE thing that says what the picture
   means and it is stated nowhere else, so at `short` it is visually hidden rather than removed. */
.gl-legend { font-size: 0.71875rem; color: var(--gl-ink-3); margin-top: 4px; }
.gl-legend-spot { color: var(--gl-spot); }

.gl-ctl { background: var(--gl-panel); border: 1px solid var(--gl-line); border-radius: 9px; padding: 11px 14px 13px; }
.gl-ctl-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin: 0 0 7px; }
.gl-val { font-family: var(--gl-mono); font-size: 0.875rem; font-weight: 600; min-width: 0; }
#glSlider { width: 100%; accent-color: var(--gl-spot); height: 22px; }
.gl-ticks { display: flex; justify-content: space-between; font-family: var(--gl-mono); font-size: 0.625rem; color: var(--gl-ink-3); }

.gl-notes { font-size: 0.75rem; color: var(--gl-warn); min-height: 1.2em; }

/* The same rows the canvas draws, for readers who are not looking at pixels. Not hidden: a
   screen reader gets the numbers, and so does anyone who prefers them. This is also the answer for
   a reader who needs text larger than a graphic can carry — it scales without limit (GLM-047). */
.gl-table { border-collapse: collapse; width: 100%; font-size: 0.75rem; margin-top: 4px; }
.gl-table caption { text-align: left; font-size: 0.6875rem; color: var(--gl-ink-2); padding-bottom: 6px; }
.gl-table th, .gl-table td {
  text-align: right;
  padding: 3px 8px;
  border-bottom: 1px solid var(--gl-line);
  font-family: var(--gl-mono);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.gl-table th { font-size: 0.625rem; letter-spacing: .08em; text-transform: uppercase; color: var(--gl-ink-3); font-family: inherit; }
.gl-v.warn { color: var(--gl-warn); }

/* A frozen board is CORRECT, not degraded — it must not wear the stale warning colour. It is
   marked at all so the reader never mistakes a closing picture for a live one that stopped
   moving, which looks identical on a chart. */
.gl-frozen { color: var(--gl-frozen); font-weight: 600; }

/* The table mirrors the DRAWN rows, and that count is a property of the selection: 8 strikes on
   the nearest expiry, 90 across the whole board. Letting the page grow with it moved the document
   from 1179px to 2725px as the slider travelled — so returning to a position put the reader
   somewhere else on the page, which reads as the chart having changed. The rows scroll inside
   their own box instead; the page keeps its height, and the chart stays where the eye left it. */
.gl-tablewrap {
  /* FIXED, not max-height: a box that only caps tall tables still grows from 3 rows to 12, so
     the page kept moving for every selection below the cap. A constant height is the whole
     point — the chart stays where the eye left it, whatever the slider does. The VALUE varies by
     breakpoint (320px of an 812px phone is 39% of the viewport spent on a mirror of the chart),
     but within a breakpoint it is a constant, which is the property that matters. */
  height: var(--gl-table-h);
  overflow-y: auto;
  overflow-x: auto;
  /* Reaching the end of the rows must not carry on into the document: the chart the reader was
     comparing against would scroll away mid-gesture (GLM-040). */
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  margin-top: 4px;
}
/* The rows below the fold must be reachable without a pointer, so the region is focusable and
   announced. A scroll container that only a mouse can move makes content that used to be on the
   page unreachable — a worse bug than the one being fixed. */
.gl-tablewrap:focus-visible { outline: 2px solid var(--gl-spot); outline-offset: 2px; }
.gl-tablewrap thead th {
  position: sticky;
  top: 0;
  background: var(--gl-panel);
}

/* What the last expiry added on its own. Without it, a slider that moves the total by 0.1% reads
   as a broken control rather than as a board whose gamma lives in two days. */
.gl-marginal { font-size: 0.71875rem; color: var(--gl-ink-2); margin-top: 2px; min-height: 1.2em; }
.gl-marginal.pos { color: var(--gl-pos-glow); }
.gl-marginal.neg { color: var(--gl-neg-glow); }

/* ================================================================ touch targets
 *
 * 44x44 CSS px minimum (Apple HIG). `any-pointer: coarse`, so a hybrid touch laptop is covered
 * too. Enlargement is by padding and min-height/min-width on the control ITSELF — never by a
 * positioned pseudo-element, which could overlap a neighbour and steal its taps.
 */
@media (any-pointer: coarse) {
  .gl-zb { min-width: 44px; min-height: 44px; }
  .gl-zb-wide { min-width: 52px; }
  .gl-btn { min-height: 44px; }
  .gl-input { min-height: 44px; }

  /* The native slider is only restyled HERE, so a fine-pointer desktop keeps its accent-color
     rendering byte for byte. A 22px-tall track with a default thumb is roughly a 22px target. */
  #glSlider {
    -webkit-appearance: none;
    appearance: none;
    display: block;
    box-sizing: border-box;
    margin: 0;
    height: 44px;
    background: transparent;
  }
  #glSlider::-webkit-slider-runnable-track {
    height: 6px;
    background: var(--gl-line-2);
    border-radius: 3px;
  }
  #glSlider::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 28px;
    height: 28px;
    margin-top: -11px;          /* centres the thumb on a 6px track */
    border-radius: 50%;
    background: var(--gl-spot);
  }
  #glSlider::-moz-range-track {
    height: 6px;
    background: var(--gl-line-2);
    border-radius: 3px;
  }
  #glSlider::-moz-range-thumb {
    width: 28px;
    height: 28px;
    border: 0;
    border-radius: 50%;
    background: var(--gl-spot);
  }
  /* A disabled slider keeps the same BOX so the layout does not move when it becomes enabled;
     only its appearance differs. */
  #glSlider:disabled::-webkit-slider-thumb { background: var(--gl-ink-4); }
  #glSlider:disabled::-moz-range-thumb { background: var(--gl-ink-4); }
}

/* ================================================================ compact — phone portrait */
@media (max-width: 599px) {
  :root {
    --gl-canvas-h: 340px;
    --gl-canvas-h: clamp(240px, 42svh, 340px);
    --gl-table-h: 220px;
  }
  .gl-wrap { padding: 12px 12px 32px; gap: 10px; }

  /* The symbol form takes the whole row with the input flexing to fill it; `min-width: 0` is what
     lets a flex item shrink below its intrinsic width instead of overflowing the row. The "board
     time" line moves to its own row beneath. */
  .gl-top { flex-direction: column; align-items: stretch; gap: 8px; }
  .gl-sym { width: 100%; }
  .gl-input { flex: 1 1 auto; width: auto; }
  .gl-btn { flex: 0 0 auto; }

  /* Deterministic 2-up with Regime spanning both, instead of auto-fit's ragged 2+1 with a
     stranded taller tile. `gl-r-wide` is a CLASS, not nth-child: an index selector would couple
     the layout silently to tile order. */
  /* Two columns at ordinary text sizes, ONE when the reader has enlarged text — the track floor
     is in `rem`, so the column count follows the font rather than being fixed at a count that was
     only ever right for one text size. Measured at 320px with 200% text: a fixed 1fr 1fr leaves
     each value 116px against a 42px font, so "−$235M" took THREE lines while "−$76M" took two,
     and the chart dropped 46px as the slider travelled. At one column the same value has 268px
     and never wraps. `.gl-r-wide` spans whatever the count is, so auto-fit cannot go ragged the
     way the unconstrained original did. */
  .gl-hud { grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr)); gap: 8px; }
  .gl-r-wide { grid-column: 1 / -1; }
  .gl-v { font-size: 1.3125rem; }
  .gl-v-regime { font-size: 1.0625rem; }

  /* TWO LINES ARE RESERVED, always. The HUD sits ABOVE the chart, so a tile that grows when its
     value happens to be longer pushes the chart down — and the chart moving as the slider travels
     is the one thing gamma-lab.css:139-147 exists to prevent. Measured at 320x568 with 200% text:
     the Net value goes from "−$76M" to "−$235M", wraps to a second line, and the chart drops 46px.
     `em`, so the reserve scales with the value's own font size.
     Two lines is enough at every supported size, not a guess: money() emits at most 9 characters
     (sign + "$" + up to "999.99" + a B/M/K suffix), which is ~225px at 200% text in monospace,
     against a tile ~150px wide at the 320px floor — so it wraps once and never twice. */
  .gl-v { min-height: 2.2em; }
}

/* ================================================================ medium — phone landscape, tablet portrait */
@media (min-width: 600px) and (max-width: 1023px) {
  :root {
    --gl-canvas-h: 380px;
    --gl-canvas-h: clamp(240px, 46svh, 380px);
    --gl-table-h: 260px;
  }
}

/* ================================================================ short — applies ON TOP of the width class
 *
 * Phone landscape. The chart, the slider and everything between them must fit one viewport, and a
 * naive stack does not: it measures ~348px against a 360px floor before browser chrome. Every box
 * in the canvasTop -> sliderBottom span is pinned here, summing to 277px (GLM-045), with the two
 * text rows given a FIXED height plus nowrap so service-supplied text cannot wrap and break it.
 */
@media (max-height: 500px) {
  :root {
    --gl-canvas-h: 240px;
    --gl-canvas-h: clamp(170px, 44svh, 240px);
    --gl-table-h: 180px;
  }
  .gl-wrap { gap: 8px; padding: 8px 12px 24px; }
  .gl-stage { padding: 6px; }
  #glCanvas { margin: 0; }

  /* Visually hidden, NOT display:none — the legend is the chart's key and is stated nowhere else,
     so removing it from the accessibility tree would take it from the reader who most needs it in
     order to save a sighted reader 18px. */
  .gl-legend {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  /* This one IS restated elsewhere — the slider's aria-valuetext announces the selection and
     .gl-val shows it directly above — so keeping it would duplicate, not add. */
  .gl-ticks { display: none; }

  .gl-ctl { padding: 10px 12px; }
  .gl-ctl-head { margin: 0 0 4px; }
  .gl-ctl-head .gl-k { display: none; }
  .gl-val {
    box-sizing: border-box;
    height: 18px;
    line-height: 18px;
    margin: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .gl-marginal {
    box-sizing: border-box;
    height: 15px;
    line-height: 15px;
    min-height: 0;
    margin: 0;
    font-size: 0.6875rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* PGL-096. The watchlist: a star beside the symbol box, and a rail of saved symbols beneath it.
   Styled here rather than inline — the public surface sends an enforcing CSP and refuses inline
   style attributes. */
.gl-star {
  background: none;
  border: 1px solid var(--gl-line, #2a2f37);
  border-radius: 6px;
  color: var(--gl-ink-2, #6b7280);
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  padding: 7px 10px;
}
.gl-star.on { color: var(--gl-spot, #f0b429); border-color: var(--gl-spot, #f0b429); }
.gl-star:disabled { opacity: 0.4; cursor: default; }
.gl-watch { align-items: center; display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.gl-watch[hidden] { display: none; }   /* [hidden] alone loses to display:flex */
.gl-watch-k {
  color: var(--gl-ink-2, #6b7280);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.gl-watch-items { display: flex; flex-wrap: wrap; gap: 6px; }
.gl-watch-item {
  background: var(--gl-panel, #12151a);
  border: 1px solid transparent;
  border-radius: 5px;
  color: var(--gl-ink-2, #9aa3af);
  cursor: pointer;
  font-family: inherit;
  font-size: 11.5px;
  letter-spacing: 0.06em;
  padding: 4px 9px;
}
/* GLM-041, same as every other hover on this page: on touch an unconditional :hover STICKS to the
   last-tapped control, so a symbol the reader tapped minutes ago keeps looking pointed-at — and on
   a watchlist rail that is actively misleading, because "highlighted" is also how the CURRENTLY
   LOADED symbol is shown (.gl-watch-item.on). This rule shipped unguarded with the watchlist and
   failed the repo's own GLM-041 check on main. */
@media (hover: hover) {
  .gl-watch-item:hover { color: var(--gl-ink, #e8eaed); }
}
.gl-watch-item.on {
  border-color: var(--gl-spot, #f0b429);
  color: var(--gl-ink, #e8eaed);
}

/* Quiet, but in the flow and always present — see gamma-lab.js. */
.gl-disclaimer {
  color: var(--gl-dim, #8fa0b3); font-size: 12px; line-height: 1.6;
  margin: 18px 0 0; max-width: 78ch;
  padding-top: 12px; border-top: 1px solid var(--gl-line, #1e2632);
}
