/* PeerTest — mobile first, one column, no framework.
   The palette is deliberately quiet: this is a tool people open for thirty
   seconds a day, and a fortnight of it should not be tiring. */

:root {
    --bg: #faf9f7;
    --card: #ffffff;
    --ink: #1e1e1c;
    --muted: #6b6b66;
    --line: #e4e2dd;
    --accent: #2f6f4e;
    --accent-ink: #ffffff;
    --danger: #a33a2c;
    --warn: #8a6d1f;
    --ok: #2f6f4e;
    --radius: 12px;
    /* The scroll-edge shadow. Dark on light, light on dark: a black shadow on a
       near-black card is no shadow at all. */
    --edge: rgba(0, 0, 0, 0.22);
    /* The mark's second tone. The long stroke takes --accent; this is the short
       one, and it is the accent of the opposite scheme rather than a new colour:
       light mode borrows the dark accent, dark mode the tint above it. */
    --mark-soft: #6bbd8e;
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #161714;
        --card: #1f211d;
        --ink: #eceae4;
        --muted: #9b9a92;
        --line: #32352f;
        --accent: #6bbd8e;
        --accent-ink: #10120f;
        --danger: #e08074;
        --warn: #d9bd6a;
        --ok: #6bbd8e;
        --edge: rgba(0, 0, 0, 0.55);
        --mark-soft: #a9dcc0;
    }
}

* { box-sizing: border-box; }

/* `nav { display: flex }` is an author rule and `[hidden] { display: none }` is
   the browser's, so the author rule wins no matter how specific the other is.
   The effect was that every signed-out visitor got the three tabs of a signed-in
   app sitting over the landing page — the app set `hidden`, and the stylesheet
   quietly ignored it. Anything given `hidden` in JS stays gone now. */
[hidden] { display: none !important; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font: 16px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
    padding-bottom: env(safe-area-inset-bottom);
}

header {
    position: sticky; top: 0; z-index: 5;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
    padding: 0.7rem 0 0;
}

/* The bar itself spans the window, because a rule that stops short of the edge
   reads as a card rather than a chrome. What sits in it takes the same 44rem
   column and the same 1rem gutter as `main`, so the wordmark and the tabs line
   up with the text under them instead of drifting into the corner on anything
   wider than a phone. */
header > * { max-width: 44rem; margin-inline: auto; padding-inline: 1rem; }

/* The lockup: the mark, then the word. Flex rather than an inline image so the
   two sit on a shared centre line at any type size, and so the gap is one
   number instead of a margin guessed against a baseline. */
header h1 { font-size: 1.05rem; margin: 0 auto 0.6rem; letter-spacing: 0.02em;
             display: flex; align-items: center; gap: 0.28em; }

/* On the legal pages the whole lockup is the way back to the app, so the anchor
   is the flex container. These three declarations were a style="" attribute on
   that anchor until now, which `style-src 'self'` refuses: the link rendered
   underlined and browser-blue in production and correct on any dev server
   without the header, which is the silent half of a CSP. */
header h1 a { color: inherit; text-decoration: none;
               display: flex; align-items: center; gap: 0.28em; }

/* The mark is drawn, not fetched: an <img> in the header is a second request
   before the first paint, and a file that carries its own colours cannot follow
   the theme. The strokes take --accent and --mark-soft, so one definition
   serves light and dark.

   Sized in em, not in the 20px its attributes carry: a reader who turns their
   browser's type up gets a larger word, and a mark that stayed 20px beside it
   would come apart as a lockup at exactly the setting where legibility already
   mattered enough to change a preference.

   The geometry is in the markup as presentation attributes and only the colour
   is here. A stylesheet pinned `immutable` for a year would otherwise meet
   newer markup and paint the two strokes as one black fill — the mark is the
   one thing on the page whose default rendering is worse than nothing. */
.mark { flex: none; width: 1.19em; height: 1.19em; }
.mark path { fill: none; stroke-width: 5; stroke-linecap: round; }
.mark .mark-long { stroke: var(--accent); }
.mark .mark-soft { stroke: var(--mark-soft); }

/* The icon set. One grid, one weight, currentColor throughout — which is what
   lets a chip keep colouring its own icon through --ok, --danger and --warn
   without a second class per state.

   Sized in em for the same reason the mark is: these sit beside 0.72rem chip
   text and 1.5rem stars, and a fixed pixel size would be wrong at one of them
   and wrong again the moment a reader turns their type up. */
.icon { flex: none; display: inline-flex; width: 1em; height: 1em; }
.icon svg { width: 100%; height: 100%; }
.icon path, .icon circle { fill: none; stroke: currentColor; }
.icon .solid { fill: currentColor; stroke: none; }

nav { display: flex; gap: 0.25rem; }

.tab {
    flex: 1;
    background: none; border: none; border-bottom: 2px solid transparent;
    color: var(--muted); font: inherit; font-size: 0.95rem;
    padding: 0.5rem 0.2rem; cursor: pointer;
}
.tab-on { color: var(--ink); border-bottom-color: var(--accent); font-weight: 600; }

main { padding: 1rem; max-width: 44rem; margin: 0 auto; }

section { margin-bottom: 1.8rem; }
section h2 { font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.07em;
             color: var(--muted); margin: 0 0 0.7rem; }

.centred { max-width: 30rem; margin: 2rem auto; }
.centred h2 { font-size: 1.4rem; text-transform: none; letter-spacing: 0; color: var(--ink); }

.card {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 0.9rem 1rem;
    margin-bottom: 0.8rem;
}
.card.slim { padding: 0.7rem 0.8rem; }
.card-head { display: flex; justify-content: space-between; align-items: baseline; gap: 0.6rem; }
.card p { margin: 0.35rem 0; }

.sub { margin-top: 0.8rem; padding-top: 0.8rem; border-top: 1px solid var(--line); }

.muted { color: var(--muted); font-size: 0.92rem; }
.small { font-size: 0.82rem; }
.mono  { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.85rem; }
.error { color: var(--danger); }

/* One to five, as buttons. Big enough to hit on a phone, and each one says
   what it is to a screen reader rather than meaning it by fill alone. */
.rate { margin-top: 0.7rem; }
.stars { display: flex; gap: 0.15rem; margin: 0.2rem 0 0.4rem; }
.star {
    min-height: 44px; min-width: 44px; padding: 0;
    background: none; border: none; color: var(--line);
    font-size: 1.5rem; line-height: 1; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
}
.star:hover, .star:focus-visible { color: var(--warn); }
.rate input { width: 100%; min-height: 44px; font: inherit; background: var(--bg);
              color: var(--ink); border: 1px solid var(--line); border-radius: 9px;
              padding: 0.5rem 0.6rem; }

/* A rejected day, said in words rather than left in a tooltip. Bordered rather
   than merely coloured: the one thing on this screen a tester has to act on
   should not depend on seeing red. */
.rejected {
    border: 1px solid var(--danger); border-radius: 9px;
    padding: 0.6rem 0.8rem; margin: 0.7rem 0; font-size: 0.92rem;
}
.rejected p { margin: 0 0 0.4rem; }
.rejected p:last-child { margin-bottom: 0; }
.rejected-head { color: var(--danger); font-weight: 600; }
.warn  { color: var(--warn); }
.ok    { color: var(--ok); font-size: 0.92rem;
         display: flex; align-items: center; gap: 0.4em; }
.ok .icon { width: 1.15em; height: 1.15em; }

.pill {
    font-size: 0.75rem; color: var(--muted);
    border: 1px solid var(--line); border-radius: 99px; padding: 0.1rem 0.5rem;
    white-space: nowrap;
}
.pill-open { color: var(--ok); }
.pill-completed { color: var(--ok); }
.pill-abandoned, .pill-removed { color: var(--danger); }

.badge {
    display: inline-block; margin-left: 0.4rem;
    background: var(--accent); color: var(--accent-ink);
    border-radius: 99px; font-size: 0.72rem; padding: 0.05rem 0.42rem; font-weight: 600;
}

button {
    font: inherit; border-radius: 9px; border: 1px solid var(--line);
    background: var(--card); color: var(--ink);
    padding: 0.55rem 0.9rem; cursor: pointer; min-height: 44px;
}
button:disabled { opacity: 0.5; cursor: progress; }
button.primary { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); font-weight: 600; }
button.danger  { color: var(--danger); }
button.big     { width: 100%; font-size: 1.05rem; margin-top: 1rem; }

.row { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.6rem; }

.field { display: block; margin: 0.7rem 0; font-size: 0.85rem; color: var(--muted); }
/* Same 44px the buttons take. A form where the button is comfortably tappable
   and the field above it is not is a form built at a desk. */
.field input, .field textarea, .field select {
    display: block; width: 100%; margin-top: 0.25rem; min-height: 44px;
    font: inherit; color: var(--ink); background: var(--bg);
    border: 1px solid var(--line); border-radius: 9px; padding: 0.55rem 0.65rem;
}
.check { display: flex; gap: 0.5rem; align-items: flex-start; font-size: 0.9rem; margin: 0.6rem 0; }

/* The Play opt-in link and the Google Group link. A tester cannot start
   without both, and they are tapped on a phone at the beginning of a fortnight,
   so they take the same 44px as everything else that is tapped. */
.links { display: flex; flex-wrap: wrap; gap: 0.9rem; margin: 0.4rem 0; font-size: 0.9rem; }
.links a { color: var(--accent); display: inline-flex; align-items: center; min-height: 44px; }

.checkin { display: flex; gap: 0.5rem; margin: 0.7rem 0; }
.checkin input { flex: 1; font: inherit; background: var(--bg); color: var(--ink); min-height: 44px;
                 border: 1px solid var(--line); border-radius: 9px; padding: 0.5rem 0.6rem; }

.mission { margin-top: 0.8rem; padding-top: 0.8rem; border-top: 1px solid var(--line); }
.mission h3, .mission h4 { margin: 0 0 0.3rem; font-size: 1rem; }

.strip { display: flex; flex-wrap: wrap; gap: 0.3rem; align-items: center; margin-top: 0.7rem; }
.chip {
    font-size: 0.72rem; border-radius: 6px; padding: 0.1rem 0.4rem;
    border: 1px solid var(--line); color: var(--muted);
    /* The mark used to be a character in the same text run, so it sat on the
       baseline and the chip looked right by accident. A drawn icon has to be
       put on the centre line deliberately. */
    display: inline-flex; align-items: center; gap: 0.3em;
}
.chip .icon { width: 1.15em; height: 1.15em; }
.chip-accepted { border-color: var(--ok); color: var(--ok); }
.chip-rejected { border-color: var(--danger); color: var(--danger); }
.chip-pending  { border-color: var(--warn); color: var(--warn); }
.chip-due      { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.chip-count    { font-size: 0.75rem; color: var(--muted); margin-left: 0.3rem; }

.shot img { max-width: 100%; border-radius: 9px; border: 1px solid var(--line); margin: 0.5rem 0; }

.wallet { display: flex; gap: 0.6rem; justify-content: space-between; }
.figure { display: flex; flex-direction: column; flex: 1; }
.figure-value { font-size: 1.5rem; font-weight: 600; }
.figure-label { font-size: 0.8rem; }
.figure-hint  { font-size: 0.72rem; color: var(--muted); }

table.totals { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
table.totals th { text-align: left; font-weight: 400; color: var(--muted); padding: 0.22rem 0; }
table.totals td { text-align: right; padding: 0.22rem 0; }

/* A sha-256 is sixty-four characters with nothing in it a browser will break
   on, and it is printed whole because a truncated digest cannot be compared,
   which is the only thing it is for. Without this the cell cannot shrink to a
   phone and table.totals — width:100% — pushes the whole page sideways. The
   day-by-day grid solves the same problem with a .scroll wrapper; a single
   value does not need one, it needs permission to wrap.
   Neither test suite can see this: jsdom has no layout engine. */
table.totals td.digest { word-break: break-all; text-align: left; line-height: 1.35; }

/* A fortnight of days does not fit across a phone, so the grid scrolls inside
   its own box rather than pushing the page sideways. The two gradients are the
   standard scroll-shadow trick: `local` backgrounds move with the content and
   `scroll` ones do not, so the shadow on each edge appears exactly when there
   is more grid that way and disappears at the ends. Without it the table looks
   finished at day seven, which for the one artefact this product exists to
   produce is the worst possible way to be wrong. */
.scroll {
    overflow-x: auto;
    background:
        linear-gradient(to right, var(--card), transparent 40px) left center / 100% 100% no-repeat local,
        linear-gradient(to left, var(--card), transparent 40px) right center / 100% 100% no-repeat local,
        linear-gradient(to right, var(--edge), transparent 14px) left center / 100% 100% no-repeat scroll,
        linear-gradient(to left, var(--edge), transparent 14px) right center / 100% 100% no-repeat scroll;
}
table.grid { border-collapse: separate; border-spacing: 0; font-size: 0.78rem; }
table.grid th, table.grid td {
    border: 1px solid var(--line); border-width: 0 1px 1px 0; padding: 2px 5px; text-align: center;
}
table.grid tr > :first-child { border-left-width: 1px; }
table.grid thead th { border-top-width: 1px; }
/* The tester's name stays put while the fortnight scrolls past it. A grid of
   several testers whose row labels have scrolled off says nothing at all. */
table.grid th:first-child {
    text-align: left; white-space: nowrap;
    position: sticky; left: 0; z-index: 1; background: var(--card);
}
.g-accepted { color: var(--ok); }
.g-rejected { color: var(--danger); }
.g-pending  { color: var(--warn); }
/* `--line` is the border colour: at 1.3:1 against the card it is a shape you
   can only see if you already know it is there. §3 says this report shows the
   days nobody turned up as plainly as the days they did, and a missed day
   drawn in the colour of a gridline is the one claim the artefact exists to
   make, unmade. --muted is the faintest thing here that is still text. */
.g-none     { color: var(--muted); }
.g-mission  { font-weight: 700; }
.g-later    { background: var(--line); opacity: 0.35; }
.own-row { margin-top: 0.4rem; }

.quote { border-left: 3px solid var(--line); margin: 0.7rem 0; padding-left: 0.8rem; }
.quote p { margin: 0 0 0.15rem; }
.quote cite { font-style: normal; font-size: 0.8rem; color: var(--muted); }
.quote-rejected { border-left-color: var(--danger); }

/* A summary is a control — tapping it is how the section opens — so it takes
   the same 44px as every other control. `display: flex` rather than the
   default `list-item` would remove the disclosure triangle, so the height is
   set with padding instead. */
details summary {
    cursor: pointer; margin-top: 0.6rem; font-size: 0.9rem;
    padding: 0.7rem 0; min-height: 44px;
}

.toast {
    position: fixed; left: 50%; bottom: 1.2rem; transform: translate(-50%, 200%);
    background: var(--ink); color: var(--bg);
    padding: 0.6rem 1rem; border-radius: 10px; max-width: 90vw;
    font-size: 0.92rem; transition: transform 0.2s ease; z-index: 20;
}
.toast-show { transform: translate(-50%, 0); }
.toast-error { background: var(--danger); color: #fff; }

.banner { border-color: var(--warn); }
.banner strong { color: var(--warn); }

/* A link that sits in a row of buttons is a control, not prose, so it gets the
   same 44px a button gets. These two sit immediately beside Sign out, and a
   22px target next to a full-height destructive one is a mis-tap waiting to
   happen on the phone this app is built for first. */
.linkish {
    color: var(--muted); font-size: 0.9rem; text-decoration: underline;
    display: inline-flex; align-items: center; min-height: 44px; padding: 0 0.4rem;
}

/* The static legal pages share this stylesheet and want prose width, not cards. */
.prose { max-width: 38rem; }
.prose h2 { font-size: 1.3rem; text-transform: none; letter-spacing: 0; color: var(--ink);
            margin: 1.8rem 0 0.5rem; }
.prose h3 { font-size: 1rem; margin: 1.4rem 0 0.3rem; }
.prose p, .prose li { color: var(--ink); }
.prose ul { padding-left: 1.2rem; }
.prose li { margin: 0.35rem 0; }
.prose .updated { color: var(--muted); font-size: 0.85rem; }

/* Inbox */
.note { display: flex; gap: 0.6rem; align-items: flex-start;
        border-bottom: 1px solid var(--line); padding: 0.6rem 0; }
.note:last-of-type { border-bottom: none; }
.note-read { opacity: 0.55; }
.note-icon { width: 1.1rem; color: var(--accent); display: flex;
              align-items: center; justify-content: center; flex: none; }
.note-icon .icon { width: 1rem; height: 1rem; }
.note p { margin: 0.1rem 0; }

/* Cohort row states */
.pill-good { color: var(--ok); }
.pill-warn { color: var(--warn); }
.pill-bad  { color: var(--danger); }

/* ── The signed-out page ─────────────────────────────────────────────────────
   Prose, not cards. Somebody arriving here is reading an argument, and a
   reading measure is about 34rem — wider and the eye loses the line. */
.landing { max-width: 34rem; margin: 0 auto 3rem; }

.landing .kicker {
    font-size: 0.78rem; letter-spacing: 0.09em; text-transform: uppercase;
    color: var(--muted); margin: 1.2rem 0 0.5rem;
}
.landing .lede {
    font-size: 1.65rem; line-height: 1.22; font-weight: 600; letter-spacing: -0.015em;
    margin: 0 0 0.7rem; text-transform: none; color: var(--ink);
}
.landing .standfirst { font-size: 1.02rem; }
.landing .standfirst em { color: var(--ink); font-style: italic; }

.landing h3 {
    font-size: 0.78rem; letter-spacing: 0.09em; text-transform: uppercase;
    color: var(--muted); margin: 2.1rem 0 0.6rem; font-weight: 600;
}
.landing p { margin: 0 0 0.9rem; }

.landing .steps { counter-reset: step; list-style: none; padding: 0; margin: 0 0 0.9rem; }
.landing .steps li {
    counter-increment: step; position: relative; padding-left: 2.1rem; margin: 0 0 0.9rem;
}
.landing .steps li::before {
    content: counter(step);
    position: absolute; left: 0; top: 0.05rem;
    width: 1.45rem; height: 1.45rem; border-radius: 50%;
    background: var(--accent); color: var(--accent-ink);
    font-size: 0.8rem; font-weight: 700;
    display: flex; align-items: center; justify-content: center;
}

.landing .rules { list-style: none; padding: 0; margin: 0 0 0.9rem; }
.landing .rules li {
    border-left: 2px solid var(--accent); padding-left: 0.85rem; margin: 0 0 0.8rem;
}

/* The link to the sample report is the proof the whole page is making, and the
   three at the bottom are the only way to read the terms before agreeing to
   them. All four are tapped on a phone, so all four are 44px. */
.landing .seelink {
    color: var(--accent); font-weight: 600;
    display: inline-flex; align-items: center; min-height: 44px;
}
/* The marketplace under the argument. Wider than the prose column, because a
   card is a card and reads badly squeezed into a measure meant for sentences. */
.landing.market { max-width: 44rem; margin-top: 0; }
.landing.market h3 { margin-bottom: 0.3rem; }

.landing .footer-links { margin-top: 1.6rem; }
.landing .footer-links a {
    color: var(--muted); text-decoration: underline;
    display: inline-flex; align-items: center; min-height: 44px;
}

/* The one full-width control on the page, and the only thing to press. */
.landing button.big { margin-top: 1.8rem; }


/* ── Keyboard and motion ─────────────────────────────────────────────────────
   The default focus ring disappears against the accent button on some
   platforms, and nothing here was drawing its own. Anyone navigating this with
   a keyboard needs to be able to see where they are. */
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 4px;
}
.tab:focus-visible { outline-offset: -2px; }

@media (prefers-reduced-motion: reduce) {
    * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ── /verify ──────────────────────────────────────────────────────────────
   ATTEST-PLAN Stage D. A page a stranger opens once, having never seen this
   site, to answer one question about a file they are holding. So the verdicts
   are a list rather than a table, and each one carries a mark as well as a
   colour: a reader who cannot distinguish the two greens still gets an answer. */
.file-label {
    display: inline-block;
    padding: 0.55rem 0.9rem;
    border: 1px solid var(--line);
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.95rem;
}
.file-label:hover { border-color: var(--ink); }
/* The input itself is reached through the label; hiding it with display:none
   would take it out of the tab order, which is the accessible-hiding mistake. */
#report-file {
    position: absolute;
    width: 1px; height: 1px;
    opacity: 0;
    overflow: hidden;
}
#report-file:focus-visible + .file-label,
.file-label:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }

ul.verdicts { list-style: none; padding: 0; margin: 1rem 0; }
ul.verdicts li {
    display: grid;
    grid-template-columns: 1.4rem 1fr;
    gap: 0.5rem;
    padding: 0.5rem 0;
    align-items: baseline;
    line-height: 1.5;
}
.verdict-mark { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

/* Sixty-four characters with nothing a browser will break on. Printed whole,
   because a truncated digest cannot be compared, which is all it is for. */
code.digest, .digest {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.8rem;
    word-break: break-all;
}

/* ── A campaign's standing (migration 34) ──────────────────────────────────
   The hidden state gets a border rather than only a colour: it is the one
   line on this screen a developer most needs to notice, and the one a colour
   alone would hide from anybody who cannot tell it from the rest. */
.standing { margin: 0.4rem 0 0.6rem; }
.standing-hidden {
    border-left: 3px solid var(--warn, #b7791f);
    padding: 0.35rem 0 0.35rem 0.75rem;
    font-size: 0.92rem;
}
.standing-hidden p { margin: 0.2rem 0; }

/* ── A campaign somebody followed a link to ────────────────────────────────
   Marked with a border as well as placement, because "this is the one you came
   for" is information and a colour alone would not carry it to everybody. */
.card-focus { border-left: 3px solid var(--accent, #2f6f4f); }

/* Day one, as numbered steps (migration 47). */
.dayone { counter-reset: step; list-style: none; padding: 0; margin: 0.6rem 0; }
.dayone li { counter-increment: step; position: relative; padding-left: 2.1rem; margin: 0 0 0.7rem; }
.dayone li::before {
    content: counter(step);
    position: absolute; left: 0; top: 0.65rem;
    width: 1.45rem; height: 1.45rem; border-radius: 50%;
    background: var(--accent); color: var(--accent-ink);
    font-size: 0.8rem; font-weight: 700;
    display: flex; align-items: center; justify-content: center;
}
.dayone li.done::before { content: '✓'; }
.dayone a { color: var(--accent); font-weight: 600; display: inline-flex; align-items: center; min-height: 44px; }
.dayone strong { display: inline-flex; align-items: center; min-height: 44px; }
.dayone p { margin: 0; }
.cohort-badge { display: flex; align-items: center; gap: 0.35rem; color: var(--accent); font-size: 0.9rem; margin: 0.3rem 0; }
.cohort-badge-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.4rem; }
.dayone-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.2rem 0.6rem; }
.landing.featured { padding-bottom: 0.5rem; }

/* /privacy/choices: the Taylab SDK draws the switch (src/taylab/choices.js),
   with class names it leaves to the product. The control is a real checkbox
   with role=switch, sized as a 44px target like every other control here. */
.tl-choices-scope { color: var(--muted); font-size: 0.92rem; margin-top: 0; }
.tl-choices-row { display: flex; align-items: flex-start; gap: 1rem; }
.tl-choices-text { flex: 1; }
.tl-choices-label { font-weight: 600; display: block; }
.tl-choices-description { margin: 0.4rem 0 0; }
.tl-choices-switch { width: 44px; height: 44px; margin: 0; flex: none; accent-color: var(--accent); }
.tl-choices-gpc, .tl-choices-status { color: var(--muted); font-size: 0.92rem; }
.tl-choices-status:empty { display: none; }
.tl-choices-gpc[hidden] { display: none; }
.tl-choices-policy a { color: var(--accent); }

/* The You tab's privacy settings: the Taylab SDK's two switches
   (src/taylab/choices.js, mountPrivacySettings), drawn like /privacy/choices. */
.tl-settings-row { display: flex; align-items: flex-start; gap: 1rem; margin-top: 0.8rem; }
.tl-settings-text { flex: 1; }
.tl-settings-label { font-weight: 600; display: block; }
.tl-settings-footer { margin: 0.4rem 0 0; color: var(--muted); font-size: 0.92rem; }
.tl-settings-switch { width: 44px; height: 44px; margin: 0; flex: none; accent-color: var(--accent); }
.tl-settings-note { color: var(--muted); font-size: 0.92rem; }
.tl-settings-row[hidden], .tl-settings-note[hidden] { display: none; }
/* SDK 1.5.0's action rows (Report a problem, Download my data): a label, a
   line under it and a button at the end, then a status line it fills. The
   report's form opens in place under them (.tl-sheet), not over the page. */
.tl-settings-action { align-items: center; }
.tl-settings-button { flex: none; }
.tl-settings-status, .tl-sheet-status { color: var(--muted); font-size: 0.92rem; margin: 0.4rem 0 0; }
.tl-settings-status:empty, .tl-sheet-status:empty { display: none; }
.tl-sheet { border-top: 1px solid var(--line, #ddd); margin-top: 0.8rem; padding-top: 0.8rem; }
.tl-sheet[hidden] { display: none; }
.tl-sheet-title { font-size: 1.05rem; margin: 0 0 0.6rem; }
.tl-sheet-label { font-weight: 600; display: block; }
.tl-sheet-note { width: 100%; min-height: 6rem; margin: 0.4rem 0 0.8rem; box-sizing: border-box; font: inherit; }
.tl-sheet-row { display: flex; align-items: center; gap: 0.6rem; }
.tl-sheet-row .tl-sheet-label { font-weight: 400; }
.tl-sheet-contact { width: 44px; height: 44px; margin: 0; flex: none; accent-color: var(--accent); }
.tl-sheet-footer { color: var(--muted); font-size: 0.92rem; }
.tl-sheet-send { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); font-weight: 600; margin-right: 0.6rem; }

/* Every page's foot: the policy and "Your Privacy Choices", on this host. */
.site-footer {
    max-width: 44rem; margin: 0 auto; padding: 0.5rem 1rem 1.5rem;
    color: var(--muted); font-size: 0.92rem;
}
.site-footer a {
    color: var(--muted); text-decoration: underline;
    display: inline-flex; align-items: center; min-height: 44px;
}
