/* Layout: one calm column of sections on Otti cream, after the practice site's
   editorial feel.

   Colour. Otti cream is the site's main colour. On the dark ground it is the primary
   button, the italic, links, hover and focus. A cream button cannot sit on a cream page,
   so in the light theme the page itself is cream and the main colour is ink. Site chrome
   takes --main and never --violet: violet is the mark's alone (--mark), and the apricot
   only its diamond. The example screens in How it works and the portal phone keep the
   app's violet (the --violet group, with --brand-line), because they depict the EMR and
   the EMR is violet; repointing them would show an app that does not exist. For the same
   reason the example screens keep the EMR's bone ground and hairline (--app-bg,
   --app-line) where the page is cream.

   Every pair below is checked to WCAG AA (text 4.5:1, large text and UI 3:1). The
   tightest are muted text on the deeper cream (4.64:1) and on a selected workflow tab
   (4.56:1), which is why --main-soft is no deeper than it is. */
:root {
  --bg: #f6efe4;             /* Otti cream, the portal's ground (tailwind `cream`) */
  --cream: #f0e7d6;          /* one step deeper: the AI band, the closing card, the stages */
  --surface: #ffffff;
  --line: #e3d9c6;
  --fg: #241d33;             /* ink */
  --muted: #6b6280;
  /* The site's chrome. */
  --main: #241d33;           /* ink on cream: the primary button, links, hover, focus */
  --on-main: #faf7f2;
  --main-soft: #efe5d2;      /* a selected workflow tab */
  --main-glow: #faf6ee;      /* the light in a stage's corner */
  --main-hi: #e8d6b1;        /* the swash under "More play." */
  --em: #241d33;             /* the hero's italic */
  --mark: #7a5ccc;           /* the mark's blocks and nothing else */
  --apricot: #f0a05a;        /* the mark's diamond and nothing else */
  --deep: #241d33;           /* the security band */
  --on-deep: #f6efe4;
  --on-deep-muted: #cbc2b4;
  --shadow: 0 1px 2px rgba(36, 29, 51, .06), 0 8px 24px rgba(36, 29, 51, .07);
  /* The app as drawn: the example screens and the portal phone. */
  --app-bg: #faf7f2;         /* ink-50, the EMR's own ground, under an example screen's insets */
  --app-line: #e8e2d7;       /* ink-200, the EMR's hairline */
  --violet: #7a5ccc;
  --violet-soft: #f1ecfb;
  --violet-text: #463a6e;    /* violet small text: 4.5:1 on the soft violet */
  --on-violet: #ffffff;
  --on-ok: #ffffff;
  --ok: #41705f;
  --ok-soft: #e3efe9;
  --frame: #241d33;          /* the example phone's bezel */
  /* The example screens in How it works borrow the EMR's own vocabulary
     (tailwind.config.js, components/StatusChip.tsx): a chip states a fact in one of
     five tones, a control is a full pill, and codes, money and labels are mono. */
  --track: #f4f0e9;          /* ink-100: segmented controls, neutral chips */
  --brand-line: #d9cdf2;     /* brand-200 */
  --ok-line: #cfe3d9;        /* success-200 */
  --neutral-ink: #463d5c;    /* ink-700 */
  --notice: #92400e; --notice-soft: #fffbeb; --notice-line: #fde68a;
  --risk: #b91c1c; --risk-soft: #fef2f2; --risk-line: #fecaca;
  --danger: #dc2626; --on-danger: #ffffff;
  --today: #b05a20; --today-soft: #fef6ee;
  --now-edge: #d4722a; --now-line: #f9d0a8;   /* accent-600, accent-200: the now line and the visit she is in */
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  --font-display: "Fraunces", Georgia, "Times New Roman", serif;
  --font-body: "Figtree", system-ui, -apple-system, "Segoe UI", sans-serif;
}
/* Dark: the ground stays dark and cream takes over from violet. The italic is a richer
   cream than the button's: the button's cream is 1.02:1 from the white headline, so in
   it "More play." stopped reading as marked at all. There is no swash in dark, and no
   light in a stage's corner, because any cream at a low alpha mixed to grey (the glow was
   a grey haze over the stages). The security band is the ground lifted, not the
   violet-deep it used to be, and its headings are the page's own text colour rather than
   the EMR's brand-50, so no violet comes back in as a surface or as type. The two blocks
   are the same; the second is for a page that sets data-theme itself. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #17131f; --cream: #201b2b; --surface: #231d30; --line: #352e44;
    --fg: #ece8f3; --muted: #a49cb6;
    --main: #f2e6cf; --on-main: #17131f; --main-soft: #2b2531;
    --main-glow: transparent; --main-hi: transparent; --em: #f3d39a;
    --mark: #a98cf0; --apricot: #f2a868;
    --deep: #2a2433; --on-deep: #ece8f3; --on-deep-muted: #bdb5c9;
    --shadow: 0 1px 2px rgba(0,0,0,.3), 0 8px 24px rgba(0,0,0,.35);
    --app-bg: #17131f; --app-line: #352e44;
    --violet: #a98cf0; --violet-soft: #2c2541; --violet-text: #c9b6f7; --on-violet: #17131f;
    --ok: #8cc7b1; --ok-soft: #1e3029; --on-ok: #17131f;
    --frame: #3a3150;
    --track: #2b2538; --brand-line: #4a3f6b; --ok-line: #2c4a3e; --neutral-ink: #d3cce0;
    --notice: #f6c66b; --notice-soft: #33280f; --notice-line: #5a4416;
    --risk: #fca5a5; --risk-soft: #3a1c23; --risk-line: #5f2a33;
    --danger: #f87171; --on-danger: #17131f; --today: #f2a868; --today-soft: #2e2219;
    --now-edge: #e88a3c; --now-line: #5a3a1e;
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #17131f; --cream: #201b2b; --surface: #231d30; --line: #352e44;
  --fg: #ece8f3; --muted: #a49cb6;
  --main: #f2e6cf; --on-main: #17131f; --main-soft: #2b2531;
  --main-glow: transparent; --main-hi: transparent; --em: #f3d39a;
  --mark: #a98cf0; --apricot: #f2a868;
  --deep: #2a2433; --on-deep: #ece8f3; --on-deep-muted: #bdb5c9;
  --shadow: 0 1px 2px rgba(0,0,0,.3), 0 8px 24px rgba(0,0,0,.35);
  --app-bg: #17131f; --app-line: #352e44;
  --violet: #a98cf0; --violet-soft: #2c2541; --violet-text: #c9b6f7; --on-violet: #17131f;
  --ok: #8cc7b1; --ok-soft: #1e3029; --on-ok: #17131f;
  --frame: #3a3150;
  --track: #2b2538; --brand-line: #4a3f6b; --ok-line: #2c4a3e; --neutral-ink: #d3cce0;
  --notice: #f6c66b; --notice-soft: #33280f; --notice-line: #5a4416;
  --risk: #fca5a5; --risk-soft: #3a1c23; --risk-line: #5f2a33;
  --danger: #f87171; --on-danger: #17131f; --today: #f2a868; --today-soft: #2e2219;
  --now-edge: #e88a3c; --now-line: #5a3a1e;
  color-scheme: dark;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
/* The sticky header is about 59px tall and see-through. Without room left for it, a link
   reached by Shift+Tab could scroll in underneath it, hidden (WCAG 2.4.11), and a jump
   to a section put the section's top behind it. */
html { scroll-padding-top: calc(64px + env(safe-area-inset-top, 0px)); }
body { margin: 0; background: var(--bg); color: var(--fg); font-family: var(--font-body); font-size: 17px; line-height: 1.6; -webkit-font-smoothing: antialiased; }
a { color: var(--main); text-underline-offset: 3px; }
a:focus-visible, button:focus-visible { outline: 2px solid var(--main); outline-offset: 3px; }
h1, h2, h3 { margin: 0; text-wrap: balance; }
p { margin: 0; }
.wrap { max-width: 72rem; margin: 0 auto; padding-inline: 20px; }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.eyebrow { font-size: .78rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }

/* ---- the wordmark: Ott + a dotless i under the apricot diamond ---- */
.wm { font-family: var(--font-body); font-weight: 700; letter-spacing: -.025em; line-height: 1; color: var(--fg); text-decoration: none; display: inline-flex; align-items: center; }
/* The diamond dot, exactly as the app's own wordmark draws it (components/Logo.tsx):
   a dotless i, and the mark's apricot diamond 0.3em wide, centred on the stem and
   lifted just clear of it. */
.wm .i { position: relative; display: inline-block; }
.wm .i svg { position: absolute; left: 0; right: 0; margin-inline: auto; top: -.06em; width: .3em; height: .3em; }

/* ---- header ---- */
.top { position: sticky; top: env(safe-area-inset-top, 0px); z-index: 10; background: color-mix(in srgb, var(--bg) 88%, transparent); backdrop-filter: blur(8px); border-bottom: 1px solid transparent; transition: border-color .2s; }
.top.scrolled { border-bottom-color: var(--line); }
.top .wrap { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding-block: 14px; }
/* The header lockup, cropped to the artwork as the app's lockup is (viewBox
   7 9.975 34.025 31.025, MARK_GEOMETRY.lockupViewBox in services/brand.ts), so the gap
   is the space between the blocks and the O and nothing else. Uncropped, the 48-unit
   square carried 4px of empty box on its right, and with a 10px gap the mark sat 14px
   from the word. The blocks stay the size they were (19.4px, .836em of the 1.45rem
   wordmark), the gap is .16em (the owner's spacing, 16 Oct, the app's too), and the
   .04em drop keeps the mark exactly where the uncropped one drew it against the word.
   The link keeps the 30px height the square gave it, so the bar and the tap target do
   not shrink with the crop. */
.brand { display: inline-flex; align-items: center; gap: .16em; min-height: 30px; font-size: 1.45rem; }
.brand > svg { flex: none; width: .9168em; height: .836em; position: relative; top: .04em; }
.nav { display: flex; align-items: center; gap: 22px; font-size: .95rem; }
.nav a { color: var(--fg); text-decoration: none; }
/* In the light theme the main colour is the ink the links are already drawn in, so a
   hover that only changed colour would not show; the underline is the hover there. */
.nav a:hover { color: var(--main); text-decoration: underline; text-decoration-thickness: 1.5px; }
.nav .hide-sm { display: none; }
@media (min-width: 760px) { .nav .hide-sm { display: inline; } }
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 10px 20px; border-radius: 999px; font: 600 .98rem var(--font-body); text-decoration: none; border: 1px solid transparent; cursor: pointer; transition: transform .15s, background .15s, box-shadow .15s; }
.btn-primary { background: var(--main); color: var(--on-main); box-shadow: 0 6px 18px color-mix(in srgb, var(--main) 20%, transparent); }
.btn-primary:hover { transform: translateY(-1px); }
.btn-quiet { background: transparent; color: var(--fg); border-color: var(--line); }
.btn-quiet:hover { border-color: var(--main); color: var(--main); }

/* ---- hero ---- */
.hero { padding-block: 56px 72px; }
.hero .wrap { display: grid; gap: 48px; align-items: center; }
@media (min-width: 1040px) { .hero .wrap { grid-template-columns: 1.05fr .95fr; } }
.hero h1 { font-family: var(--font-display); font-weight: 400; font-size: clamp(2.6rem, 6.2vw, 4.6rem); line-height: 1.02; letter-spacing: -.02em; margin-top: 18px; }
/* "More play." keeps its italic, so colour is never the only thing marking it. On the
   cream page it sits on a deeper cream swash, drawn as an underline so it runs under the
   glyphs and follows the words when the line wraps; dark has no swash (--main-hi). */
.hero h1 em { font-style: italic; color: var(--em); text-decoration: underline var(--main-hi); text-decoration-thickness: .16em; text-underline-offset: -.08em; text-decoration-skip-ink: none; }
/* Forced colours (Windows High Contrast) repaint every text decoration in the text
   colour, whatever --main-hi says, so the swash became a solid bar through the bottoms
   of the letters, in dark too, where it is not meant to exist. The italic still marks
   the words there. */
@media (forced-colors: active) { .hero h1 em { text-decoration: none; } }
.hero .lead { margin-top: 22px; font-size: 1.15rem; color: var(--muted); max-width: 34rem; }
.hero .ctas { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; }
.hero .note { margin-top: 16px; font-size: .9rem; color: var(--muted); }

/* ---- the hero's product loop ----
   Fourteen seconds of the real app with a made-up family: a note is typed and signed,
   then the family's phone shows the visit's summary. It replaced the mark building
   itself beside three floating chips, two of which named a different child and a
   deadline the footage never reaches. The footage draws its own browser window and
   phone, so it gets no device frame: a bezel round it read as a stock mock-up and
   brought the purple back. The box is the footage's own ground, so nothing flashes on
   a dark page while the poster loads. */
.reel { position: relative; }
.reel-figure { margin: 0; }
.reel-box { position: relative; }
.reel-glass { position: relative; aspect-ratio: 16 / 9; border-radius: 20px; overflow: hidden; border: 1px solid var(--line); background: #f7f3ee; box-shadow: 0 1px 2px rgba(20, 15, 30, .08), 0 22px 48px -18px rgba(20, 15, 30, .30); }
.reel-glass img, .reel-glass video { display: block; width: 100%; height: 100%; object-fit: cover; }
/* The poster is an image in the markup; site.js lays the video over it only where the
   loop will play (see the note there on why the page carries no <video>). */
.reel-glass video { position: absolute; inset: 0; }
/* One chip over the bottom edge, and only what the footage shows: the note signed, its
   two goals marked worked (only one carries an assist level, so not "scored"), and the
   summary on the family's phone. It hangs past the box's left edge only where the
   hero's column gap leaves room for it; in one column that would run off the page. */
.reel-chip { position: absolute; z-index: 2; left: 16px; bottom: 0; display: flex; align-items: center; gap: 10px; max-width: 290px; padding: 10px 14px; background: var(--surface); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow); font-size: .86rem; line-height: 1.3; transform: translateY(50%); animation: rise .6s ease-out .6s both; }
.reel-chip b { display: block; font-weight: 600; }
.reel-chip span { color: var(--muted); }
.reel-chip .dot { flex: none; width: 10px; height: 10px; border-radius: 50%; }
@media (min-width: 1040px) { .reel-chip { left: -22px; } }
@keyframes rise { from { transform: translateY(calc(50% + 14px)); opacity: 0; } to { transform: translateY(50%); opacity: 1; } }
/* The caption answers what a child's name on an EMR's homepage invites: is that a real
   patient? It clears the chip's overhang. The control sits beside it, off the footage
   (on it, it covered the family phone's tab bar), and exists because the loop runs
   longer than five seconds beside the text (WCAG 2.2.2). It is the figure's sibling,
   not part of the caption, so the figure is named by the caption alone. */
.reel-figure figcaption { display: flex; align-items: center; min-height: 36px; margin-top: 46px; padding-right: 120px; font-size: .86rem; color: var(--muted); }
.reel-toggle { position: absolute; right: 0; bottom: 0; display: inline-flex; align-items: center; gap: 8px; min-height: 36px; padding: 6px 14px 6px 12px; border-radius: 999px; border: 1px solid var(--line); background: transparent; color: var(--fg); font: 600 .86rem var(--font-body); cursor: pointer; }
.reel-toggle:hover { border-color: var(--main); color: var(--main); }
.reel-toggle[hidden] { display: none; }
.reel-toggle svg { width: 14px; height: 14px; }
.reel-toggle[data-state="playing"] .i-play, .reel-toggle[data-state="paused"] .i-pause { display: none; }
/* A phone gets the poster and nothing else: at this width no text in the footage can be
   read, and the loop is about a megabyte on a cellular connection. site.js never asks
   for the file at 560px or below (the same query), and the chip and the control go too. */
@media (max-width: 560px) {
  .reel-glass { border-radius: 16px; }
  .reel-chip, .reel-toggle { display: none; }
  .reel-figure figcaption { min-height: 0; margin-top: 10px; padding-right: 0; font-size: .82rem; }
}
@media (prefers-reduced-motion: reduce) { .reel-toggle { display: none; } }

/* ---- sections ---- */
section { padding-block: 72px; }
.section-head { max-width: 40rem; display: grid; gap: 14px; margin-bottom: 36px; }
.section-head h2 { font-family: var(--font-display); font-weight: 400; font-size: clamp(2rem, 4.2vw, 3rem); line-height: 1.08; letter-spacing: -.015em; }
.section-head p { color: var(--muted); font-size: 1.08rem; }

/* The AI section is the deeper cream band between the workflows and the family portal,
   so the page alternates its two creams into the deep security band. The security page's
   alternate sections (.band) are the same band, in one rule so the two cannot drift. */
.ai, .band { background: var(--cream); border-block: 1px solid var(--line); }

/* features */
.features { display: grid; gap: 0; border-top: 1px solid var(--line); }
@media (min-width: 760px) { .features { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 48px; } }
@media (min-width: 1040px) { .features { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.feature { padding-block: 24px; border-bottom: 1px solid var(--line); display: grid; gap: 8px; align-content: start; }
.feature h3 { font-size: 1.08rem; font-weight: 600; display: flex; align-items: center; gap: 10px; }
.feature h3::before { content: ""; width: 9px; height: 9px; border-radius: 2px; background: var(--main); transform: rotate(45deg); flex: none; }
.feature p { color: var(--muted); }

/* trust */
.trust { background: var(--deep); color: var(--on-deep); }
.trust .section-head p { color: var(--on-deep-muted); }
.trust .fineprint { margin-top: 32px; color: var(--on-deep-muted); font-size: .95rem; max-width: none; }
.trust .eyebrow { color: var(--on-deep-muted); }
.facts { display: grid; gap: 18px; }
@media (min-width: 900px) { .facts { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.fact { border-top: 1px solid color-mix(in srgb, var(--on-deep) 22%, transparent); padding-top: 18px; display: grid; gap: 8px; align-content: start; }
.fact h3 { font-size: 1.1rem; font-weight: 600; }
.fact p { color: var(--on-deep-muted); }

/* The security page (security.html). It is built from the home page's parts: the hero,
   the deep band with its facts, the features grid and the closing card. What follows is
   only what those parts lacked. Pairs checked to WCAG AA in both themes: muted on the
   deeper cream band 4.64:1 light and 6.39:1 dark, on-deep on the deep band 14.16:1 and
   12.44:1.
   Links in the deep band: --main is the band's own ink in the light theme, so a link
   drawn in it, and the focus ring round it, would vanish there. */
.trust a { color: var(--on-deep); text-decoration-thickness: 1px; }
.trust a:hover { text-decoration-thickness: 2px; }
.trust a:focus-visible { outline-color: var(--on-deep); }
/* The home page's way from its Security section to this page. */
.trust .more { margin-top: 16px; font-weight: 600; }
/* Four longer items read better as two columns than as three and one. */
@media (min-width: 1040px) { .features.features-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* A company's two lines: what it does for Otti, and what it handles. */
.does { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 6px 14px; margin: 0; }
.does dt { font-size: .74rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); padding-top: .25em; }
.does dd { margin: 0; color: var(--fg); }
/* Small print under a section on the page ground; the deep band's own is above. */
.fineprint { margin-top: 28px; color: var(--muted); font-size: .95rem; max-width: 46rem; }
.points { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; max-width: 46rem; }
/* Inside the closing card, the list keeps the measure of the paragraphs around it. */
.closing .points { max-width: 36rem; }
/* A page with nothing beside its hero copy: one column, so the right half is not an
   empty box waiting for a picture. */
.hero.hero-solo .wrap { grid-template-columns: minmax(0, 1fr); }

/* origin */
.origin blockquote { margin: 0; font-family: var(--font-display); font-style: italic; font-size: clamp(1.6rem, 3.4vw, 2.4rem); line-height: 1.25; max-width: 46rem; }
.origin p { margin-top: 18px; color: var(--muted); max-width: 40rem; }

/* closing */
.closing .card { border-radius: 28px; padding: 36px 26px; background: var(--cream); border: 1px solid var(--line); display: grid; gap: 18px; justify-items: start; }
.closing h2 { font-family: var(--font-display); font-weight: 400; font-size: clamp(1.9rem, 4vw, 2.8rem); line-height: 1.1; }
.closing p { color: var(--muted); max-width: 36rem; }
footer { padding-block: 32px 48px; color: var(--muted); font-size: .9rem; }
footer .wrap { display: flex; flex-wrap: wrap; gap: 14px 28px; align-items: center; justify-content: space-between; }
footer nav { display: flex; flex-wrap: wrap; gap: 18px; }
footer a { color: var(--muted); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* Formerly inline style attributes, moved here so the Content-Security-Policy can refuse
   inline styles outright. */
.dot-ok { background: var(--ok); }
.origin blockquote, blockquote.spaced { margin-top: 16px; }
.wm.footer-wm { font-size: 1.1rem; }
.wm .year { font-weight: 400; color: var(--muted); }

/* The family portal: what families get, beside an example phone. The phone is drawn in
   HTML with working tabs rather than a screenshot, so it stays sharp at any size and
   follows dark mode. The practice name and logo on it are made up, which is the point:
   a family sees their own practice there, and Otti only in the small print. */
.portal-grid { display: grid; gap: 40px; align-items: start; }
@media (min-width: 1040px) { .portal-grid { grid-template-columns: minmax(0, 1.2fr) minmax(0, .8fr); gap: 64px; } }
.portal-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
@media (min-width: 640px) { .portal-list { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 32px; } }
.portal-list li, .points li { position: relative; padding-left: 22px; color: var(--muted); }
.portal-list li::before, .points li::before { content: ""; position: absolute; left: 2px; top: .62em; width: 8px; height: 8px; border-radius: 2px; background: var(--main); transform: rotate(45deg); }
/* The diamond markers are drawn as backgrounds, which forced colours repaint as Canvas,
   so with Windows High Contrast on they vanished. Draw them in the text colour there. */
@media (forced-colors: active) {
  .portal-list li::before, .points li::before, .feature h3::before { forced-color-adjust: none; background: CanvasText; }
}
.portal-list b { color: var(--fg); font-weight: 600; }
.portal-note { margin: 24px 0 0; color: var(--muted); font-size: .95rem; }
.phone-wrap { display: flex; flex-direction: column; align-items: center; gap: 12px; }
.phone-hint { margin: 0; font-size: .85rem; color: var(--muted); text-align: center; }
.phone { width: min(310px, 100%); border-radius: 42px; padding: 11px; background: var(--frame); box-shadow: var(--shadow); }
.p-screen { border-radius: 32px; background: var(--bg); padding: 18px 14px 12px; display: grid; gap: 12px; }
.p-top { display: flex; align-items: center; gap: 10px; }
.p-logo { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; background: var(--ok-soft); color: var(--ok); flex: none; }
.p-practice { font-weight: 600; font-size: .92rem; line-height: 1.2; }
.p-tabs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; padding: 4px; border-radius: 13px; background: var(--surface); border: 1px solid var(--line); }
.p-tabs [role="tab"] { font: inherit; font-size: .85rem; font-weight: 600; color: var(--muted); background: none; border: 0; border-radius: 9px; min-height: 36px; cursor: pointer; }
.p-tabs [role="tab"][aria-selected="true"] { background: var(--violet-soft); color: var(--violet-text); }
/* The three screens share one grid cell, so the phone is as tall as its fullest screen
   and keeps that height when the tabs change, as a real phone does; sized by their own
   content, the frame jumped 170px between Home and Bills. A hidden screen keeps its
   place but is invisible, out of the tab order and out of the accessibility tree, which
   visibility: hidden does at once. Without that line all three draw over each other:
   the panel's own display value beats the browser's [hidden] rule. */
.p-panels { display: grid; }
.p-panel { grid-area: 1 / 1; display: grid; gap: 10px; align-content: start; }
.p-panel[hidden] { visibility: hidden; }
.p-card { background: var(--surface); border: 1px solid var(--line); border-radius: 16px; padding: 12px 14px; display: grid; gap: 3px; }
.p-label { margin: 0; font-size: .7rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.p-strong { margin: 0; font-weight: 600; }
.p-sub { margin: 0; font-size: .84rem; color: var(--muted); }
.p-text { margin: 0; font-size: .88rem; line-height: 1.5; }
.p-chip, .p-btn { justify-self: start; margin-top: 6px; font-size: .78rem; font-weight: 600; border-radius: 999px; padding: 4px 11px; }
.p-chip { color: var(--violet-text); background: var(--violet-soft); }
.p-btn { color: var(--on-violet); background: var(--violet); border-radius: 10px; padding: 7px 14px; }
.p-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.p-chips span { font-size: .74rem; font-weight: 600; color: var(--ok); background: var(--ok-soft); border-radius: 999px; padding: 3px 9px; }
.p-bar { height: 8px; margin: 6px 0 4px; border-radius: 999px; background: var(--violet-soft); overflow: hidden; }
.p-bar span { display: block; width: 66%; height: 100%; border-radius: inherit; background: var(--violet); transition: width .3s ease; }
/* The example home program can be ticked, the way a parent would (site.js keeps the bar
   and the tally in step). The 66% above is two of three, for a page without script. */
.p-checks { display: grid; gap: 6px; margin-top: 4px; }
.p-check { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 38px; padding: 6px 9px; border-radius: 10px; border: 1px solid var(--line); background: var(--bg); color: var(--fg); font: inherit; font-size: .86rem; text-align: left; cursor: pointer; }
.p-check::before { content: ""; flex: none; width: 16px; height: 16px; border-radius: 5px; border: 1.5px solid var(--muted); display: grid; place-items: center; font-size: 10px; font-weight: 700; color: var(--on-ok); transition: background .15s, border-color .15s; }
.p-check[aria-pressed="true"] { color: var(--muted); }
.p-check[aria-pressed="true"]::before { content: "\2713"; background: var(--ok); border-color: var(--ok); }
.p-spark { display: flex; align-items: flex-end; gap: 6px; height: 46px; margin: 8px 0 4px; }
.p-spark i { flex: 1; border-radius: 4px 4px 2px 2px; background: var(--violet); }
.p-spark i:nth-child(1), .p-spark i:nth-child(2) { height: 20%; opacity: .5; }
.p-spark i:nth-child(3), .p-spark i:nth-child(4) { height: 40%; opacity: .7; }
.p-spark i:nth-child(5), .p-spark i:nth-child(6) { height: 60%; }
.p-link { color: var(--violet); font-weight: 600; }
.p-powered { margin: 0; text-align: center; font-size: .7rem; color: var(--muted); }

/* How it works: six workflows beside a stage. Picking one drops its example screens
   onto the stage one after another, and then the one detail each screen is about (a
   date worked out, a chip, the button the step ends on) pops in. Until the stage scrolls into view the motion waits
   (site.js), so it plays when someone is looking rather than at page load, out of sight.
   The section sits straight under the hero on the same cream ground, so a hairline keeps
   it from reading as part of it. The tabs and the stage are the site's chrome and take
   the main colour; the screens on the stage are the app's and keep its violet. */
.flows { border-top: 1px solid var(--line); }
.wf { display: grid; gap: 16px; align-items: stretch; }
@media (min-width: 1100px) { .wf { grid-template-columns: minmax(0, .62fr) minmax(0, 1.38fr); gap: 28px; } }

/* Six tabs have to fit a 390px phone without a sideways scroll: two columns there, three
   on a tablet, and the full list with each step's line of description beside the stage
   from 1100px, where there is room for it. */
.steps { display: grid; gap: 8px; grid-template-columns: repeat(2, minmax(0, 1fr)); align-content: start; }
@media (min-width: 700px) { .steps { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .steps { grid-template-columns: minmax(0, 1fr); } }
.step { text-align: left; display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 10px; row-gap: 2px; align-items: baseline; align-content: start; padding: 10px 12px; border-radius: 14px; border: 1px solid var(--line); background: var(--surface); color: var(--fg); font: inherit; cursor: pointer; transition: border-color .15s, background .15s; min-height: 44px; }
.step .n { grid-column: 1; font-family: var(--font-mono); font-size: .72rem; font-weight: 600; color: var(--muted); }
.step .t { grid-column: 2; font-weight: 600; font-size: .9rem; line-height: 1.3; }
.step .s { grid-column: 2; font-size: .86rem; line-height: 1.4; color: var(--muted); display: none; }
/* A two-column grid of tabs at 320px leaves a title about 87px: "evaluations" in the
   fallback font (the first paint with display=swap, or wherever Google Fonts is blocked)
   ran past the tab's padding. A little less padding and type there gives it room, and a
   word that still does not fit breaks rather than spilling into the next tab. */
@media (max-width: 399px) { .step { padding-inline: 10px; column-gap: 8px; } .step .t { font-size: .86rem; overflow-wrap: anywhere; } }
@media (min-width: 1100px) { .step { padding: 12px 16px; border-radius: 16px; } .step .t { font-size: 1rem; } .step .s { display: block; } }
.step:hover { border-color: color-mix(in srgb, var(--main) 45%, var(--line)); }
.step[aria-selected="true"] { border-color: var(--main); background: var(--main-soft); }
.step[aria-selected="true"] .n { color: var(--fg); }

/* The six panels share one grid cell from 700px, so the stage keeps the height of its
   fullest workflow and nothing below it jumps when the tabs change. A hidden panel keeps
   its place but is invisible, out of the tab order and out of the accessibility tree,
   which visibility: hidden does at once (the example phone further down does the same).
   On a phone each panel takes its own height: the tabs sit above the stage there, so a
   change of height moves only what is below it. */
.wf-panels { display: grid; min-width: 0; }
.wf-panel { grid-area: 1 / 1; display: flex; flex-direction: column; gap: 12px; min-width: 0; border-radius: 24px; }
.wf-panel[hidden] { display: none; }
.wf-panel:focus-visible { outline: 2px solid var(--main); outline-offset: 4px; }
@media (min-width: 700px) { .wf-panel[hidden] { display: flex; visibility: hidden; } }
.wf-caption { color: var(--muted); font-size: .95rem; padding-inline: 4px; }

.wf-stage { position: relative; flex: 1; display: grid; gap: 12px; align-content: start; padding: 14px; border-radius: 24px; border: 1px solid var(--line); background: radial-gradient(110% 80% at 80% 10%, var(--main-glow), transparent 60%), var(--cream); overflow: hidden; }
.wf-a { margin-right: 5%; } .wf-b { margin-left: 5%; } .wf-c { margin-right: 2%; }
/* Two columns of screens from 700px: the first top left, the second to its right and a
   little lower, the third under the first, so they read in the order they drop. */
@media (min-width: 700px) {
  .wf-stage { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; padding: 22px; align-content: center; border-radius: 28px; }
  .wf-a { grid-column: 1; grid-row: 1; margin: 0; align-self: start; }
  .wf-b { grid-column: 2; grid-row: 1 / span 2; margin: 24px 0 0; align-self: start; }
  .wf-c { grid-column: 1; grid-row: 2; margin: 0; align-self: start; }
}

/* One column that may not grow past the card. An implicit grid column is `auto`, which
   widens to its longest unbreakable row: at 320px the one-line question in Ask the notes
   pushed the AI badge and the Ask button out of the card, where the stage cut them off.
   A card is drawn on the EMR's own ground and hairline, not the site's: its insets (a goal
   row, a fold, a tag) and its borders take --bg and --line, and the page's are Otti cream,
   which is the portal's ground but not the EMR's. Repointing the two inside the card keeps
   every part below as the app draws it. The portal phone keeps the page's --bg, because
   the portal really is cream. */
.wf-card { --bg: var(--app-bg); --line: var(--app-line); background: var(--surface); border: 1px solid var(--line); border-radius: 16px; box-shadow: var(--shadow); padding: 14px 16px; display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; align-content: start; font-size: .84rem; line-height: 1.4; min-width: 0; }
@keyframes drop { from { transform: translateY(-38px); opacity: 0; } to { transform: none; } }
.drop-in { animation: drop .6s cubic-bezier(.2,.9,.3,1.25) both; }
.wf-a.drop-in { animation-delay: .1s; } .wf-b.drop-in { animation-delay: .5s; } .wf-c.drop-in { animation-delay: .9s; }
.pop { animation: pop .4s cubic-bezier(.2,.9,.3,1.3) both; }
.wf-a .pop { animation-delay: .8s; } .wf-b .pop { animation-delay: 1.2s; } .wf-c .pop { animation-delay: 1.6s; }
.ui-rows li:nth-child(2) .pop { animation-delay: .95s; }
.ui-rows li:nth-child(3) .pop { animation-delay: 1.1s; }
.ui-rows li:nth-child(4) .pop { animation-delay: 1.25s; }
.wf-c .ui-cites.pop, .wf-c .ui-line + .ui-line .pop, .ui-kinds li:nth-child(2) .pop { animation-delay: 1.85s; }
.ui-cells .ui-field:nth-child(2) .pop { animation-delay: .95s; }
.ui-cells .ui-field:nth-child(3) .pop { animation-delay: 1.1s; }
@keyframes pop { from { opacity: 0; transform: scale(.82); } to { opacity: 1; transform: none; } }
.flows.wait .drop-in, .flows.wait .pop, .flows.wait .wave i { animation-play-state: paused; }

/* ---- the example screens' parts, each after the EMR component it imitates ---- */
.wf-head { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 8px; min-width: 0; }
.wf-head b { font-weight: 600; font-size: .95rem; }
.push { margin-left: auto; }
/* The AI badge: the one mark that tells a reader which steps the AI does. */
.ai-tag { display: inline-block; padding: 1px 7px; border-radius: 6px; font-size: .68rem; font-weight: 700; letter-spacing: .06em; color: var(--violet-text); background: var(--violet-soft); }
/* LABEL in components/surfaces.ts: mono, small, capitals, never a sentence. */
.ui-label { font-family: var(--font-mono); font-size: .64rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.ui-label.is-good { color: var(--ok); }
.ui-meta, .ui-small { color: var(--muted); font-size: .76rem; }
.ui-text { color: var(--fg); }
.ui-strong { color: var(--fg); font-weight: 700; }
.ui-mono { font-family: var(--font-mono); font-size: .72rem; font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; }
.ui-money { font-family: var(--font-mono); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ui-money.big { font-size: 1.15rem; }
.ui-split-line { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.ui-split-line.start { justify-content: flex-start; }
.ui-num { font-family: var(--font-mono); font-size: .72rem; font-weight: 600; color: var(--muted); }
/* StatusChip: a fact, never a control, so a small radius where a control is a pill. */
.ui-chip { display: inline-flex; align-items: center; flex: none; padding: 3px 6px; border: 1px solid var(--line); border-radius: 6px; font-size: .62rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; line-height: 1; white-space: nowrap; color: var(--neutral-ink); background: var(--track); }
.ui-chip.is-brand { color: var(--violet-text); background: var(--violet-soft); border-color: var(--brand-line); }
.ui-chip.is-good { color: var(--ok); background: var(--ok-soft); border-color: var(--ok-line); }
.ui-chip.is-notice { color: var(--notice); background: var(--notice-soft); border-color: var(--notice-line); }
/* Button: every control a full pill; drawn, not pressable, since nothing here is live. */
.ui-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 6px 13px; border-radius: 999px; border: 1px solid var(--line); background: var(--surface); color: var(--fg); font-size: .74rem; font-weight: 600; line-height: 1.2; white-space: nowrap; }
.ui-btn.primary { background: var(--violet); border-color: var(--violet); color: var(--on-violet); }
.ui-btn.danger { background: var(--danger); border-color: var(--danger); color: var(--on-danger); }
.ui-btn.small { padding: 3px 9px; font-size: .7rem; }
.ui-btn.quiet { border-color: transparent; background: none; color: var(--muted); }
.ui-btn.block { display: flex; width: 100%; white-space: normal; text-align: center; }
.ui-stop { width: 9px; height: 9px; border-radius: 2px; background: currentColor; }
.ui-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.ui-actions.end { justify-content: flex-end; }
/* Tabs: the segmented control on a tinted track. */
.ui-seg { display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 3px; border-radius: 11px; background: var(--track); }
.ui-seg span { padding: 3px 9px; border-radius: 8px; font-size: .68rem; font-weight: 600; color: var(--muted); }
.ui-seg .on { background: var(--surface); color: var(--violet-text); box-shadow: 0 1px 2px rgba(36, 29, 51, .12); }
.ui-seg.wide { display: flex; }
.ui-seg.wide span { flex: 1 1 auto; text-align: center; padding-inline: 6px; }
.ui-field { display: grid; gap: 4px; min-width: 0; }
.ui-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.ui-input { display: block; padding: 5px 9px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); color: var(--fg); font-size: .8rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ui-input.multi { white-space: normal; color: var(--fg); line-height: 1.45; }
.ui-box { display: grid; gap: 2px; justify-items: start; padding: 8px 10px; border-radius: 12px; background: var(--bg); border: 1px solid var(--line); }
.ui-box.small { font-size: .74rem; color: var(--muted); }

/* The intake's agreements, each with the chart's own chip. */
.ui-rows { list-style: none; margin: 0; padding: 0; display: grid; border-top: 1px solid var(--line); }
.ui-rows li { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--line); }
.ui-rows li:last-child { border-bottom: 0; padding-bottom: 0; }
/* The evaluation's suggestion: beside the box, and nothing changes until Keep. */
.ui-suggest { display: grid; gap: 8px; padding: 10px 12px; border-radius: 12px; border: 1.5px solid var(--brand-line); background: color-mix(in srgb, var(--violet-soft) 70%, var(--surface)); }
.ui-suggest-text { padding: 8px 10px; border-radius: 10px; background: var(--surface); border: 1px solid var(--brand-line); color: var(--fg); }
/* Goals, with the plan's LTG/STG numbering. */
.ui-goals { list-style: none; margin: 0; padding: 0; display: grid; gap: 5px; }
.ui-goals li { display: flex; align-items: baseline; gap: 8px; font-weight: 600; }
.ui-goals li.sub { font-weight: 400; padding-left: 14px; }
.ui-tag { flex: none; font-family: var(--font-mono); font-size: .62rem; font-weight: 600; padding: 2px 5px; border: 1px solid var(--line); border-radius: 5px; color: var(--muted); background: var(--bg); }
.ui-line { color: var(--muted); }
.ui-line b { color: var(--fg); font-weight: 600; white-space: nowrap; }
.ui-line b.pop { display: inline-block; }

/* The schedule list: time, name, chip, and a coloured edge that says the same as the chip. */
.ui-list { border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.ui-dayhead { display: flex; justify-content: space-between; gap: 8px; padding: 6px 10px; background: var(--today-soft); color: var(--today); font-size: .7rem; font-weight: 600; }
/* The chip drops under the name where the row is too narrow for both, rather than
   the name shrinking to an ellipsis: at 320px the time and the chip left "Nora B."
   12px. The names are what this card is about. */
.ui-row { display: flex; flex-wrap: wrap; align-items: center; gap: 3px 8px; min-height: 38px; padding: 6px 10px 6px 8px; border-top: 1px solid var(--line); border-left: 3px solid var(--line); }
.ui-row .ui-chip { margin-left: auto; }
.ui-row.is-good { border-left-color: var(--ok); } .ui-row.is-notice { border-left-color: var(--now-edge); } .ui-row.is-brand { border-left-color: var(--violet); }
/* Today as the list folds it (services/scheduleView.ts foldDay): the visits already
   over fold into one "N done" line, the now line goes where now falls, and a free stretch
   of half an hour or more is a line that books it. */
.ui-fold { display: flex; align-items: center; gap: 8px; min-height: 32px; padding: 4px 10px; border-top: 1px solid var(--line); background: var(--bg); color: var(--neutral-ink); font-size: .74rem; }
.ui-fold > span:first-child { flex: 1; min-width: 0; }
.ui-fold-act { flex: none; font-size: .7rem; font-weight: 600; color: var(--violet-text); }
.ui-now { display: flex; align-items: center; gap: 6px; min-height: 20px; padding: 0 10px 0 8px; background: var(--today-soft); border-block: 1px solid var(--now-line); }
.ui-now-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--now-edge); }
.ui-now-rule { flex: 1; border-top: 2px solid var(--now-edge); }
.ui-now-label { flex: none; font-family: var(--font-mono); font-size: .6rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--today); white-space: nowrap; }
.ui-gap { display: flex; align-items: center; min-height: 26px; padding: 2px 10px; border-top: 1px dashed var(--line); color: var(--muted); font-size: .7rem; font-weight: 500; }
.ui-time { flex: none; width: 54px; font-family: var(--font-mono); font-size: .72rem; font-weight: 600; color: var(--neutral-ink); font-variant-numeric: tabular-nums; }
.ui-time small { font-size: .62rem; color: var(--muted); }
.ui-name { flex: 1 0 auto; font-weight: 700; white-space: nowrap; }
.ui-video { flex: none; color: var(--violet); }
.ui-options { display: flex; flex-wrap: wrap; gap: 6px; }
.ui-options span { padding: 4px 9px; border-radius: 999px; border: 1px solid var(--line); font-size: .7rem; font-weight: 600; color: var(--muted); background: var(--surface); }
.ui-options .on { border-color: var(--violet); color: var(--violet-text); background: var(--violet-soft); }

/* Home's next-session card and the prep sheet. */
.ui-person { display: flex; align-items: center; gap: 12px; }
.ui-person > span:last-child { display: grid; gap: 2px; justify-items: start; min-width: 0; }
.ui-person b { font-size: 1.05rem; font-weight: 700; }
.ui-avatar { width: 44px; height: 44px; flex: none; display: grid; place-items: center; border-radius: 50%; border: 1px solid var(--brand-line); background: var(--violet-soft); color: var(--violet-text); font-weight: 700; }
.ui-alert { display: flex; align-items: center; gap: 6px; padding: 4px 8px; border-radius: 8px; border: 1px solid var(--risk-line); background: var(--risk-soft); color: var(--risk); font-size: .72rem; font-weight: 700; }
.ui-alert svg { flex: none; }
.ui-prep { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.ui-tagchip { padding: 2px 8px; border-radius: 6px; border: 1px solid var(--line); background: var(--bg); color: var(--neutral-ink); font-size: .72rem; font-weight: 600; }
.ui-bar { padding: 7px 10px; border-radius: 10px; border: 1px solid var(--line); color: var(--muted); font-size: .76rem; }
.ui-bar b { color: var(--fg); font-weight: 600; }
/* The Ask button goes under the question when both do not fit on one line, so the
   question is read whole at phone width instead of ending in an ellipsis. */
.ui-ask { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.ui-ask .ui-input { flex: 1 1 auto; }
.ui-ask .ui-btn { margin-left: auto; }
.ui-receipt { font-family: var(--font-mono); font-size: .64rem; line-height: 1.5; color: var(--muted); }
.ui-cites { display: flex; flex-wrap: wrap; gap: 5px; }
.ui-cite { font-family: var(--font-mono); font-size: .62rem; padding: 2px 6px; border: 1px solid var(--line); border-radius: 6px; color: var(--muted); background: var(--surface); }

/* The session note. */
.ui-soap { display: flex; gap: 8px; color: var(--muted); }
.ui-soap b { flex: none; width: 18px; height: 18px; display: grid; place-items: center; border-radius: 5px; font-family: var(--font-mono); font-size: .66rem; color: var(--bg); background: var(--fg); }
.ui-goalrow { display: grid; gap: 4px; padding: 8px 10px; border-radius: 12px; border: 1px solid var(--line); background: var(--bg); }
.ui-goalrow p:first-child { display: flex; align-items: baseline; gap: 8px; font-weight: 600; }
.ui-read { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.ui-quote { font-style: italic; font-size: .76rem; color: var(--ok); }
.ui-stepper { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px 14px; }
.ui-stepper li { display: flex; align-items: center; gap: 6px; font-size: .76rem; font-weight: 600; }
.ui-stepper li::before { content: "\2713"; width: 16px; height: 16px; flex: none; display: grid; place-items: center; border-radius: 50%; font-size: 10px; font-weight: 700; color: var(--on-ok); background: var(--ok); }

/* The evaluation (pages/InitialEvaluation.tsx): sections under their numerals, the
   observation areas she adds, a tool's score form with the manual's own column names
   and every value typed by her, and the reflexes with their statuses. */
.ui-secs { list-style: none; margin: 0; padding: 0; display: grid; border-top: 1px solid var(--line); }
.ui-secs li { display: flex; align-items: baseline; gap: 8px; padding: 5px 0; border-bottom: 1px solid var(--line); font-weight: 600; }
.ui-secs .ui-num { width: 22px; flex: none; }
.ui-sec { display: flex; align-items: baseline; gap: 8px; margin-top: 4px; }
.ui-sec b { font-weight: 600; font-size: .9rem; }
.ui-area { font-size: .76rem; font-weight: 700; color: var(--fg); }
.ui-tool { display: grid; gap: 6px; padding: 10px 12px; border-radius: 12px; border: 1px solid var(--line); }
.ui-tool b { font-weight: 700; }
.ui-rowname { font-weight: 600; font-size: .8rem; }
.ui-cells { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px 8px; }
.ui-cells .wide { grid-column: 1 / -1; }
/* A select: the field with its caret. */
.ui-select { position: relative; padding-right: 24px; }
.ui-select::after { content: ""; position: absolute; right: 10px; top: 50%; width: 6px; height: 6px; border-right: 1.5px solid var(--muted); border-bottom: 1.5px solid var(--muted); transform: translateY(-70%) rotate(45deg); }
.ui-reflex { display: grid; gap: 4px; }
.ui-reflex > span:first-child { font-weight: 600; font-size: .8rem; }
.ui-suggest-title { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; color: var(--fg); }
.ui-suggest-title svg { flex: none; color: var(--violet); }
.ui-count { font-weight: 400; }
/* Reports: one row per kind, with its count line. */
.ui-kinds { list-style: none; margin: 0; padding: 0; display: grid; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.ui-kinds li { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 12px; border-top: 1px solid var(--line); }
.ui-kinds li:first-child { border-top: 0; }
.ui-kinds li > span:first-child { display: grid; gap: 2px; min-width: 0; }
.ui-kinds b { font-weight: 600; }
.ui-kinds li > span:first-child > span { font-size: .72rem; font-weight: 600; color: var(--neutral-ink); font-variant-numeric: tabular-nums; }
.ui-kinds .pop { justify-self: start; }
.ui-chev { flex: none; color: var(--muted); font-size: 1.1rem; line-height: 1; }

/* Billing. */
.ui-code { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.ui-code > span:first-child:not(.ui-mono) { display: grid; gap: 1px; }
.ui-code > .ui-mono:first-child + span { flex: 1; }
.ui-figs { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 10px; }

/* The waveform moves for about four seconds and then rests, so nothing on the page keeps
   moving on its own past five seconds (WCAG 2.2.2) without a way to stop it. */
.wave { display: flex; align-items: center; gap: 3px; height: 26px; }
.wave i { flex: 1; max-width: 5px; height: 100%; border-radius: 3px; background: var(--violet); transform-origin: center; animation: talk .45s ease-in-out 1.2s 9 alternate both; }
.wave i:nth-child(3n+1) { height: 90%; animation-duration: .5s; }
.wave i:nth-child(3n+2) { height: 45%; animation-duration: .38s; }
.wave i:nth-child(3n) { height: 70%; animation-duration: .42s; }
@keyframes talk { from { transform: scaleY(.3); } to { transform: scaleY(1); } }
