/* Palette and typography from the official Intentional Parents Branding Guide
   2023 (V3 Refresh), pages 5-6. Not sampled, not invented.

     GREENS (brand main)      #052313  #244436  #5C765D  #74826F
     GREEN SHADE (secondary)  #9EC590
     TERTIARY / BACKGROUND    #CAD5B7  #DCDCCB
     ACCENT + BUTTONS         #E3D094
     NEUTRALS (brand base)    #F2F0ED  #FEFCF0  #C9C0B1  #F4EFE9
     BLACK                    #231E15

     Header font    Articulat CF v2
     Body font      Inter Regular
     Accent font    FreightMicro Pro Light Italic

   All three are self-hosted from the licensed files, subset to Latin-1 plus the
   punctuation the UI renders (curly quotes, ellipsis, the play triangle) and
   converted to woff2: 1MB of source OTF/TTF down to 96KB total. Self-hosting
   also avoids a Google Fonts round trip and the privacy question that carries.

   font-display:swap so text paints immediately in the fallback and reflows when
   the face lands, rather than showing nothing. */

@font-face {
  font-family: "Articulat CF";
  src: url("fonts/articulat-500.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Articulat CF";
  src: url("fonts/articulat-600.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Articulat CF";
  src: url("fonts/articulat-700.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("fonts/inter-var.woff2") format("woff2");
  font-weight: 100 900;   /* variable */
  font-style: normal; font-display: swap;
}
@font-face {
  font-family: "FreightMicro Pro";
  src: url("fonts/freightmicro-italic.woff2") format("woff2");
  font-weight: 300; font-style: italic; font-display: swap;
}

:root {
  --green-deep:  #052313;
  --green:       #244436;
  --green-mid:   #5C765D;
  --green-muted: #74826F;
  --green-soft:  #9EC590;
  --tertiary:    #CAD5B7;
  --tertiary-2:  #DCDCCB;
  --accent:      #E3D094;   /* ACCENT + BUTTONS, per brand guide */
  --base:        #F2F0ED;
  --base-warm:   #FEFCF0;
  --base-tan:    #C9C0B1;
  --base-blush:  #F4EFE9;
  --ink:         #231E15;

  --font-head: "Articulat CF", "Inter", ui-sans-serif, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --font-body: "Inter", ui-sans-serif, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-accent: "FreightMicro Pro", Georgia, "Times New Roman", serif;

  --radius: 10px;
  --max: 720px;
}

* { box-sizing: border-box; }

/* Any class setting display (grid/flex) overrides the hidden attribute's
   default display:none, so "hidden" elements stay visible and, when they are
   fixed-position overlays, keep swallowing clicks. Make hidden authoritative. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  background: var(--base-warm);
  color: var(--ink);
  font: 400 16px/1.6 var(--font-body);
  -webkit-font-smoothing: antialiased;
}

h1, h2 { font-family: var(--font-head); font-weight: 600; letter-spacing: -0.01em; }

/* ---------- password gate ---------- */
.gate {
  position: fixed; inset: 0;
  display: grid; place-items: center;
  background: var(--green-deep);
  padding: 24px;
}
/* `display: grid` overrides the hidden attribute's default display:none, so a
   hidden fixed-position overlay keeps covering the page and swallowing clicks:
   after entering the password the Ask button was unclickable. */
.gate[hidden] { display: none; }
.gate-card {
  background: var(--base-warm);
  border-radius: 14px;
  padding: 34px 28px;
  width: 100%; max-width: 380px;
  text-align: center;
}
.gate-card h1 { margin: 10px 0 4px; font-size: 25px; }
.gate-card .sub { margin: 0 0 20px; color: var(--green-muted); font-size: 14px; }
.gate-card form { display: flex; gap: 8px; }
.gate-card input {
  flex: 1; padding: 11px 12px; font: inherit;
  border: 1px solid var(--base-tan); border-radius: var(--radius);
  background: #fff;
}
.gate-card button {
  padding: 11px 20px; font: 600 15px var(--font-head);
  background: var(--green); color: var(--base-warm);
  border: 0; border-radius: var(--radius); cursor: pointer;
}
.err { color: #8C2F2F; font-size: 13px; margin: 12px 0 0; }

/* ---------- layout ---------- */
main { max-width: var(--max); margin: 0 auto; padding: 30px 20px 80px; }

header { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 24px; }
/* Centre the badge on the TITLE, not on the whole text block.
   `align-items: flex-start` aligned it to the top of a two-line block (h1 plus
   the italic subtitle), which left it sitting high against the h1 it reads
   with. The h1 is 27px on a 38px badge, so nudging down by half that
   difference lands the badge's centre on the title's centre. */
header .mark { margin-top: 5px; }
header h1 { margin: 0; font-size: 27px; }
header .sub {
  margin: 3px 0 0; color: var(--green-muted); font-size: 15px;
  font-family: var(--font-accent); font-style: italic; font-weight: 300;
}

/* The official Intentional four-circle mark, inline rather than a file or a
   data URI: the widget ships in two hand-synced copies and the edge-function
   copy has no sibling files to reference (docs/widget-two-copies.md).
   Geometry is taken from Design Files/Intentional Parents/SVG/Intentional
   Icon_Black.svg, not eyeballed: that export repeats the same three paths
   three times, so this is the same shape written once. Ring radius 55.28 is
   the stroke CENTRE, midway between the source path's outer 58.72 and inner
   51.835; stroke-width 6.88 is the difference between them. */
.mark {
  width: 38px; height: 38px; flex: 0 0 38px;
  display: grid; place-items: center;
  background: var(--green); color: var(--tertiary);
  border-radius: 50%;
}
/* 22px inside the 38px badge. The old asterisk was a glyph and carried its
   own side bearings; an SVG has none, so matching the glyph's 19px left the
   mark visibly cramped. 22px is ~58% of the badge, which keeps the square
   mark's 31px diagonal clear of the 38px circle. */
.mark svg { width: 22px; height: 22px; display: block; overflow: visible; }
/* currentColor so the mark follows .mark's colour and stays one thing to
   change. The rings are stroked, the fourth circle is solid: that contrast is
   the logo, so do not "simplify" it to four identical dots. */
/* stroke-width is in viewBox units and scales with the mark, which is what
   keeps the ring weight proportional at any size. Do NOT add
   vector-effect: non-scaling-stroke here: at 19px that renders a hairline and
   the rings stop matching the brand weight. */
.mark circle {
  fill: none; stroke: currentColor; stroke-width: 6.88;
}
.mark circle.solid { fill: currentColor; stroke: none; }
.gate-card .mark { margin: 0 auto; }

/* ---------- ask ---------- */
#ask-form { display: flex; gap: 10px; align-items: flex-start; }
#q {
  flex: 1; padding: 13px 14px; font: inherit;
  border: 1px solid var(--base-tan); border-radius: var(--radius);
  background: #fff; resize: vertical; min-height: 58px;
  /* No fixed height, and no `height` from the rows attribute winning over the
     inline height autoGrow() sets.
     `field-sizing: content` grows the box to its text natively where it is
     supported; `overflow-y: hidden` keeps a scrollbar from appearing in the
     gap before autoGrow() runs on older engines. Without this a long question
     was clipped mid-sentence with nothing to indicate more text existed:
     inline height read 128px while the computed height stayed 78px, because
     `align-items: flex-start` on the row-direction parent sized the item to
     its content box. */
  field-sizing: content;
  overflow-y: hidden;
  align-self: stretch;
}
#q:focus { outline: 2px solid var(--green-soft); outline-offset: 1px; }

/* Accent #E3D094 is a soft gold: it needs dark ink, not white, to stay legible. */
#send {
  padding: 15px 24px; font: 600 15px var(--font-head);
  background: var(--accent); color: var(--green-deep);
  border: 0; border-radius: var(--radius); cursor: pointer;
  min-height: 58px;
}
#send:hover { filter: brightness(.96); }
#send:disabled { opacity: .55; cursor: default; }

.examples {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin-top: 12px; font-size: 13px; color: var(--green-muted);
}
.examples button {
  font: inherit; color: var(--green); background: var(--base-blush);
  border: 1px solid var(--tertiary-2); border-radius: 999px;
  padding: 6px 13px; cursor: pointer;
}
.examples button:hover { border-color: var(--green-soft); background: #fff; }

/* ---------- read more ---------- */
/* 64px, and it earns the space. The button is the one thing to press after
   reading, so it needs to sit clearly APART from the last line rather than
   look like a continuation of the paragraph. 22px then 40px both still read as
   scrunched on the live page (Christian, 2026-09-11). */
#readmore-wrap { margin: 44px 0 4px; text-align: center; }
#readmore-wrap[hidden] { display: none; }
/* An expand control, not a tab pair. It sits between the answer and the
   follow-up box, so it reads as the first of two next moves rather than as
   navigation. Left-aligned with the prose it belongs to, not centred like the
   tablist was: it is a continuation of the answer, not a header above it. */
.readmore {
  min-height: 44px;              /* touch target, as the tabs had */
  padding: 10px 22px;
  font-family: var(--font-head); font-weight: 600; font-size: 14px;
  /* Filled, not outlined: same treatment as .feedback button.on, so the one
     thing to press after reading looks pressable (Christian, 2026-09-11). */
  color: var(--base-warm); background: var(--green);
  border: 1px solid var(--green); border-radius: 999px;
  cursor: pointer;
  transition: filter 140ms ease;
}
.readmore:hover { filter: brightness(1.12); }
.readmore:focus-visible { outline: 2px solid var(--green-soft); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .readmore { transition: none; } }
/* The panels are focusable so a keyboard user can move straight to the prose,
   but they are not interactive, so no focus ring. */
#panel-short:focus, #panel-long:focus { outline: none; }
#panel-short:focus-visible, #panel-long:focus-visible {
  outline: 2px solid var(--green-soft); outline-offset: 4px;
}

/* ---------- answer ---------- */
#result { margin-top: 32px; }
.status { font-size: 13px; color: var(--green-muted); min-height: 20px; }
.status.safety { color: #8C2F2F; font-weight: 600; }

.answer { font-size: 17px; line-height: 1.74; white-space: pre-wrap; }

/* ---------- the longer answer ---------- */
/* It used to carry the same .answer class as the short one with nothing between
   them, so expanding read as the answer growing rather than a second, fuller
   take. The rule, the heading and the left border together mark it as the
   deeper version of what was just read. */
#long-wrap {
  margin-top: 26px;
  padding-top: 22px;
  border-top: 1px solid var(--tertiary-2);
}
#long-wrap[hidden] { display: none; }
.long-title {
  margin: 0 0 12px;
  font: 600 13px/1.3 var(--font-head);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--green-muted);
}
/* Indented against a soft rule, so the block reads as nested detail rather
   than as a second answer competing with the first. */
#panel-long {
  padding-left: 18px;
  border-left: 2px solid var(--tertiary-2);
}
@media (max-width: 1079px) {
  #panel-long { padding-left: 13px; }
}
/* The summary is what most parents read, so it gets the larger size. The body
   behind the expand stays at 17px. */
.summary { font-size: 18px; }
/* Was an 11px superscript with a 2px hit area: invisible as an affordance and
   a third of the 44px touch minimum, so nobody clicked it. Now a pill that
   reads as a control. It still scrolls to the clip card rather than opening
   the episode: the card carries the quote, speaker, timestamp and Watch
   button, so the parent lands on a play button with the context first.
   vertical-align is `middle` with a zero line-height override so the pill
   sits on the text baseline without stretching the 1.74 prose rhythm. */
.answer sup {
  display: inline-block; vertical-align: middle;
  min-width: 21px; padding: 1px 6px; margin: 0 2px;
  font-size: 12px; line-height: 17px; font-weight: 700; text-align: center;
  color: var(--green); background: var(--base-blush);
  border: 1px solid var(--tertiary-2); border-radius: 999px;
  cursor: pointer;
}
.answer sup:hover {
  color: var(--base-warm); background: var(--green); border-color: var(--green);
}
.answer sup:focus-visible { outline: 2px solid var(--green-soft); outline-offset: 2px; }

/* ---------- clips ---------- */
#clips-wrap h2 {
  font-size: 12px; text-transform: uppercase; letter-spacing: .1em;
  color: var(--green-muted); margin: 32px 0 12px;
  padding-top: 18px; border-top: 1px solid var(--tertiary-2);
}
.clips { display: grid; gap: 10px; }
.clip {
  background: #fff; border: 1px solid var(--tertiary-2);
  border-radius: var(--radius); padding: 15px 16px;
}
.clip.target { border-color: var(--green-soft); box-shadow: 0 0 0 2px rgba(158,197,144,.3); }

/* ---------- skeleton cards ---------- */
/* Shown the instant a question is submitted and replaced when the citations
   arrive. Typed questions wait 1-5s for retrieval, and the screen used to hold
   one static line for all of it. These use the real .clip box, so nothing
   shifts when the real cards land. Cached chips never see them. */
.clip-skeleton { opacity: .6; }
.sk {
  display: block; background: var(--tertiary-2); border-radius: 4px;
  animation: sk-pulse 1.4s ease-in-out infinite;
}
.sk-n     { width: 22px; height: 16px; border-radius: 4px; display: inline-block; }
.sk-title { width: 62%;  height: 14px; display: inline-block; }
.sk-meta  { width: 45%;  height: 11px; margin-top: 9px; }
.sk-line  { width: 100%; height: 10px; margin-top: 8px; }
.sk-line.short { width: 70%; }
@keyframes sk-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
/* A pulsing placeholder is motion for its own sake to anyone who asked for
   less of it; the shape still communicates "cards are coming". */
@media (prefers-reduced-motion: reduce) { .sk { animation: none; } }
.clip-head { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.clip-n {
  font: 700 11px var(--font-body); color: var(--green-deep);
  background: var(--tertiary); border-radius: 4px; padding: 2px 7px;
}
.clip-title { font-family: var(--font-head); font-weight: 600; font-size: 15px; }
.clip-meta {
  display: flex; align-items: center; gap: 6px;
  font-size: 12.5px; color: var(--green-muted); margin: 5px 0 9px;
}
/* Host headshot. Sized well above display size in the source (220px) so it
   stays sharp on retina. */
.clip-face {
  width: 30px; height: 30px; border-radius: 50%;
  object-fit: cover; flex: none;
  border: 1px solid var(--tertiary-2);
}
.clip-quote {
  font-family: var(--font-accent); font-style: italic; font-weight: 300; font-size: 15px;
  color: var(--green-deep);
  border-left: 2px solid var(--tertiary); padding-left: 11px; margin: 0 0 11px;
}
.clip a.watch {
  display: inline-block; font: 600 13.5px var(--font-head);
  color: var(--green-deep); background: var(--accent); text-decoration: none;
  padding: 8px 14px; border-radius: 7px;
}
.clip a.watch:hover { filter: brightness(.96); }
/* Audio-only episodes: RedCircle mid-roll ad insertion shifts playback by up to
   ~2 minutes, so these deliberately have no seek control. */
.noseek { font-size: 12.5px; color: var(--green-muted); }

/* ---------- feedback ---------- */
.feedback {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  margin-top: 28px; padding-top: 16px; border-top: 1px solid var(--tertiary-2);
  font-size: 13.5px; color: var(--green-muted);
}
.feedback button {
  font: inherit; background: #fff; border: 1px solid var(--tertiary-2);
  border-radius: 999px; padding: 6px 13px; cursor: pointer;
}
.feedback button.on { background: var(--green); color: var(--base-warm); border-color: var(--green); }
.feedback input {
  flex: 1; min-width: 180px; font: inherit; padding: 7px 10px;
  border: 1px solid var(--tertiary-2); border-radius: var(--radius);
}
.thanks { color: var(--green-mid); font-weight: 600; }

/* A percentage width on a phone leaves each half under 90px, so the pill goes
   full width below the breakpoint where the touch target starts to matter. */
@media (max-width: 560px) {
  /* Phones get a slightly tighter version of the same breathing room. NOTE
     this block is max-width 560px, NOT the 1079px one: an earlier fix assumed
     the wrong breakpoint and changed a rule that was never applying. */
  #readmore-wrap { margin: 34px 0 4px; }
  .readmore { width: 100%; }
}
@media (max-width: 560px) {
  #ask-form { flex-direction: column; }
  /* The form stacks, so BOTH children need to fill the width. #send already
     did; #q kept `flex: 1`, which in a column flex container sizes on the
     cross axis to content, so the input sat at about half width while the
     Ask button ran edge to edge. */
  #q { width: 100%; align-self: auto; }
  #send { width: 100%; }
  header h1 { font-size: 23px; }

  /* One chip per row, all the same width.
     The chips were `flex-wrap: wrap` inline items, so each pill was as wide as
     its own text: a short question got a small pill and a long one wrapped to
     two lines, which read as lopsided. Stacking them makes the group a tidy
     column and lets the text left-align instead of centring on two lines. */
  .examples { flex-direction: column; align-items: stretch; }
  .examples > span { margin-bottom: 2px; }
  .examples button { width: 100%; text-align: left; }
}

/* ---------- long answer: the on-demand wait ---------- */
/* The long answer is a second request now, so there is a real gap between the
   click and the first token. An empty panel reads as broken, so say what is
   happening in Intentional's voice rather than showing a bare spinner. */
.searching {
  display: flex; align-items: center; gap: 10px;
  color: var(--green-muted); font-size: 15px;
  margin: 4px 0 0; font-style: italic;
}
.dots { display: inline-flex; gap: 4px; flex: 0 0 auto; }
.dots i {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--green-soft); display: block;
  animation: pulse 1.25s ease-in-out infinite;
}
.dots i:nth-child(2) { animation-delay: .18s; }
.dots i:nth-child(3) { animation-delay: .36s; }
@keyframes pulse {
  0%, 100% { opacity: .3; transform: scale(.85); }
  40%      { opacity: 1;  transform: scale(1); }
}
/* Respect the setting: without motion the dots hold at a readable opacity
   rather than freezing at whatever frame they stopped on. */
@media (prefers-reduced-motion: reduce) {
  .dots i { animation: none; opacity: .65; }
}

/* ---------- Stay in the Loop ---------- */
/* A right-hand margin rail on wide screens, stacked under the answer on
   narrow ones. The page is a 720px single column, so the rail lives OUTSIDE
   that column: `main` becomes a grid at >=1080px and the aside takes the
   second track. Below that the grid collapses to one column and the aside
   simply follows the content, which is the right reading order on a phone
   anyway (answer first, promotion after).

   Deliberately not `position: fixed`. A rail that follows the scroll competes
   with the answer a parent is reading. */
@media (min-width: 1080px) {
  main {
    max-width: calc(var(--max) + 260px);
    display: grid;
    grid-template-columns: var(--max) 220px;
    column-gap: 40px;
    align-items: start;
  }
  /* Everything except the rail stays in the first column. */
  main > *:not(.loop) { grid-column: 1; }
  .loop {
    grid-column: 2;
    grid-row: 1 / span 40;   /* span the content so it starts at the top */
    position: sticky;
    top: 30px;
  }
}
.loop { margin: 40px 0 0; }
.loop h2 {
  font-family: var(--font-head); font-size: 12px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--green-muted); margin: 0 0 12px;
}
.loop-grid { display: grid; gap: 16px; }
.loop-card {
  display: block; text-decoration: none; color: var(--green);
  border-radius: 10px; overflow: hidden;
}
.loop-card img {
  display: block; width: 100%; height: auto;
  border-radius: 10px; border: 1px solid var(--tertiary-2);
  background: var(--base);
}
.loop-card span {
  display: block; margin-top: 7px;
  font-size: 13px; line-height: 1.35; font-weight: 500;
}
.loop-card:hover span { text-decoration: underline; }
.loop-card:focus-visible {
  outline: 2px solid var(--green-soft); outline-offset: 3px;
}
/* On narrow screens the four cards read better side by side than as a
   single tall stack that pushes the feedback prompt off the page. */
@media (max-width: 1079px) {
  .loop-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }

  /* Stacked, the rail goes between the ANSWER and the citation cards.
     Three positions were wrong before this one. Before #result (its DOM
     position, which the desktop grid needs) put four promo cards between the
     question and the answer. `order: 1` on a `main` flex column moved it past
     the whole of #result, so it landed below the cards AND the feedback
     prompt, half off the bottom of the page. Above the cards is the spot: the
     answer is what the parent came for, the cards are where they go next, and
     the promotions sit at that hand-off rather than interrupting or being
     buried.

     Done by making #result the flex container and using order on ITS children,
     with the rail slotted in by `order: 2`. The clips and feedback live inside
     #result, which is why ordering `main`'s children could not place anything
     between them. */
  .loop { margin: 40px 0 8px; }
}

/* ---------- the short answer's episode link ---------- */
/* One per answer, on the episode that best answers the question. Underlined
   rather than coloured: the answer is prose a parent is reading, and a green
   word mid-sentence reads as a UI control. */
/* The one episode the short answer sends a parent to. Italic and arrowed so it
   is legible as a destination before anyone hovers it (Christian, 2026-09-11):
   underline alone read as ordinary emphasis in the middle of prose.
   Done in CSS, not in the model's output, so the prompt and every already
   cached answer stay untouched. */
.ep-link {
  color: inherit;
  /* Bold AND italic, no arrow: the glyph read as clutter mid-sentence and the
     weight carries it better (Christian, 2026-09-11). */
  font-style: italic;
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: var(--green-soft);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
.ep-link:hover { text-decoration-color: var(--green); }
.ep-link:focus-visible {
  outline: 2px solid var(--green-soft); outline-offset: 2px; border-radius: 2px;
}

/* ---------- follow-up questions ---------- */
/* Deliberately a SECONDARY control: single line, lighter border, smaller type
   than the main question box. Typing a follow-up over the original question
   reads as losing it, so this is a separate place to ask. */
.followup { margin: 22px 0 0; }
#fu-form { display: flex; gap: 8px; align-items: stretch; }
#fu-input {
  flex: 1; padding: 10px 13px; font: inherit; font-size: 15px;
  border: 1px solid var(--tertiary-2); border-radius: var(--radius);
  background: #fff; color: var(--green);
}
#fu-input::placeholder { color: var(--green-muted); }
#fu-input:focus { outline: 2px solid var(--green-soft); outline-offset: 1px; }
#fu-send {
  flex: 0 0 auto; min-width: 44px; padding: 0 14px;
  font: 600 17px/1 var(--font-head);
  background: var(--tertiary-2); color: var(--green);
  border: 0; border-radius: var(--radius); cursor: pointer;
}
#fu-send:hover { background: var(--tertiary); }
#fu-send:disabled, #fu-input:disabled { opacity: .55; cursor: default; }
/* A text button, not a second call to action: starting over is the escape
   hatch, not the invitation. */
.linky {
  margin: 8px 0 0; padding: 0; background: none; border: 0;
  font: inherit; font-size: 13px; color: var(--green-muted);
  text-decoration: underline; cursor: pointer;
}
.linky:hover { color: var(--green); }

/* Each follow-up is a <details>: the question stays visible when collapsed, so
   a parent can see what they asked and reopen any answer with its text intact. */
#thread { display: grid; gap: 14px; margin-top: 22px; }
.qa { border-top: 1px solid var(--rule, var(--tertiary-2)); padding-top: 14px; }
.qa > summary {
  cursor: pointer; list-style: none;
  font: 600 15px/1.4 var(--font-head); color: var(--green);
  display: flex; gap: 8px; align-items: baseline;
}
.qa > summary::-webkit-details-marker { display: none; }
/* A caret that turns, so open/closed is obvious without reading the text. */
.qa > summary::before {
  content: "›"; flex: 0 0 auto; font-size: 17px; line-height: 1;
  color: var(--green-muted); transition: transform 120ms ease;
}
.qa[open] > summary::before { transform: rotate(90deg); }
.qa > summary:focus-visible {
  outline: 2px solid var(--green-soft); outline-offset: 3px; border-radius: 3px;
}
.qa-body { margin-top: 10px; }
@media (prefers-reduced-motion: reduce) {
  .qa > summary::before { transition: none; }
}
