/* ==========================================================================
   Turtle Labs components.

   One definition per thing, used by all seven sites. A surface supplies
   colour and nothing else.

   This exists because the same handful of components had been written eight
   and nine times over. A text input was styled independently as `form input`,
   `.referform input`, `.sheet-form input`, `.audit-form input`, `.reaudit
   input`, `.field input`, `.signin-form input` and `.inline-form input`; the
   selectable choice card as `.pf-opt`, `.q-scale`, `.q-opts` and `.g-opt`.
   Every correction then had to be made eight times, and the ones that were
   missed are what a design review keeps finding.

   The rule for adding to this file: a component goes here the second time it
   is needed. The rule for using it: a site may set tokens, and may not
   redefine padding, radius, border or type. checks/components.js enforces
   the second half.

   Tokens a surface is expected to provide, all with fallbacks here so a
   component still renders if one is missing:

     --bg --bg2 --surface --text --muted --faint --line --line2
     --cta --cta-ink --cta-text --accent-soft
     --r-sm --r-md --r-lg --r-pill

   The accent is the one that bites. Three surfaces name it --cta, three name
   it --accent, and tl-system named it --green and nothing else, so every
   filled component on the group, Useful Store and BrandOS surfaces resolved
   its ink to the literal #fff and rendered white text on a white card in the
   light theme. Each surface now declares --cta and --cta-ink, and the
   fallbacks below chain through all three names so a new surface that forgets
   is merely wrong rather than invisible. checks/tokens.js asserts the
   declaration.

   ========================================================================== */

/* ---- rhythm --------------------------------------------------------------
   Two primitives instead of a margin on every element. Stacks own the space
   between their children, so a component dropped into one is spaced without
   knowing where it is.
   ------------------------------------------------------------------------ */
.tl-stack        { display: flex; flex-direction: column; gap: var(--tl-gap, 18px); }
.tl-stack-sm     { --tl-gap: 10px; }
.tl-stack-lg     { --tl-gap: 28px; }
.tl-row          { display: flex; flex-wrap: wrap; gap: var(--tl-gap, 14px); align-items: center; }
.tl-row-tight    { --tl-gap: 8px; }
/* A heading in a row is one of the row's items, not a paragraph: its bottom
   margin pushed the text up off the icon's centre line. Only direct children
   of a card had the margin cleared, and these sit inside .tl-row. */
.tl-row > :is(h2, h3, h4) { margin: 0; }

/* ---- section heading -----------------------------------------------------
   Eyebrow, heading, lede. Written out per section across four sites, with the
   gaps between the three parts different every time.
   ------------------------------------------------------------------------ */
.tl-head { display: flex; flex-direction: column; gap: 12px; margin-bottom: 32px; }
.tl-head .tl-eyebrow { margin: 0; }
.tl-head h2, .tl-head h3 { margin: 0; }
.tl-head p { margin: 0; color: var(--muted); font-size: clamp(15.5px, 1.6vw, 18px);
             line-height: 1.6; max-width: 62ch; }
.tl-head.is-centred { align-items: center; text-align: center; }
.tl-head.is-centred p { margin-inline: auto; }

.tl-eyebrow { font-size: 11.5px; letter-spacing: .16em; text-transform: uppercase;
              font-weight: 800; color: var(--cta-text, var(--cta, var(--accent, var(--muted))));
              display: inline-flex; align-items: center; gap: 10px; }
.tl-eyebrow::before { content: ''; width: 22px; height: 2px; border-radius: 2px;
                      background: currentColor; flex: none; }

/* ---- surfaces ------------------------------------------------------------
   One card. Variants change colour and weight, never the geometry, which is
   why a corner or a padding can be corrected in one place.
   ------------------------------------------------------------------------ */
.tl-card {
  background: var(--surface, var(--bg2));
  border: 1px solid var(--line2, var(--line));
  border-radius: var(--r-lg, 18px);
  padding: clamp(20px, 2.2vw, 30px);
  display: flex; flex-direction: column; gap: 14px;
}
.tl-card.is-quiet   { background: transparent; }
.tl-card.is-raised  { background: var(--bg2, var(--surface)); }
.tl-card.is-accent  { border-color: var(--cta, var(--accent, var(--green))); }
/* The one a reader is meant to take: filled, not outlined. */
.tl-card.is-chosen  { background: var(--cta, var(--accent, var(--green))); border-color: var(--cta, var(--accent, var(--green)));
                      color: var(--cta-ink, var(--accent-ink, var(--green-ink, #fff))); position: relative; }
.tl-card.is-chosen :is(p, li, span):not(.tl-badge) { color: inherit; opacity: .82; }
.tl-card.is-chosen :is(h2, h3, h4, strong) { color: inherit; opacity: 1; }
.tl-card > :is(h2, h3, h4) { margin: 0; }
.tl-card > p:not([class]) { margin: 0; color: var(--muted); line-height: 1.6; }
.tl-card > p { margin: 0; line-height: 1.6; }

/* Equal-width card grids, one definition. */
.tl-cards { display: grid; gap: clamp(12px, 1.4vw, 20px);
            grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--tl-col, 260px)), 1fr)); }
.tl-cards.is-wide   { --tl-col: 320px; }
.tl-cards.is-narrow { --tl-col: 200px; }

/* ---- badge ---------------------------------------------------------------
   The pill. Takes its colour from --tone, so one rule covers a status, a
   category and a price label.
   ------------------------------------------------------------------------ */
.tl-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px; border-radius: var(--r-pill, 999px);
  font-size: 11.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  background: color-mix(in srgb, var(--tone, var(--cta, #888)) 14%, transparent);
  color: var(--tone-ink, var(--tone, var(--cta, var(--accent, var(--green)))));
  border: 1px solid color-mix(in srgb, var(--tone, var(--cta, #888)) 34%, transparent);
  white-space: nowrap;
}
.tl-badge.is-solid { background: var(--tone, var(--cta, var(--accent, var(--green)))); color: var(--cta-ink, var(--accent-ink, var(--green-ink, #fff)));
                     border-color: transparent; }
/* Sitting on the lip of a card, which is where "most chosen" goes. */
.tl-badge.is-pinned { position: absolute; top: -11px; left: 22px; }
.tl-card:has(> .tl-badge.is-pinned) { padding-top: clamp(26px, 2.6vw, 34px); }
@supports not selector(:has(*)) {
  .tl-card > .tl-badge.is-pinned + * { margin-top: 8px; }
}
/* A badge pinned to a filled card takes the card's ink, not the spectrum hue
   its position happens to give it: a crimson tag on a green card reads as a
   warning rather than as a recommendation. */
.tl-card.is-chosen > .tl-badge.is-solid {
  background: var(--cta-ink, var(--accent-ink, #fff));
  color: var(--cta, var(--accent, var(--green)));
}

/* And a button on one. The secondary weight is accent-tinted, which is
   accent-on-accent once the card is filled with the accent: measured at 1:1,
   which is not low contrast, it is no contrast. On a filled card the button
   inverts, the way the plan cards already do it by hand. */
.tl-card.is-chosen .btn,
.tl-card.is-chosen .btn.primary {
  background: var(--cta-ink, var(--accent-ink, #fff));
  border-color: var(--cta-ink, var(--accent-ink, #fff));
  color: var(--cta, var(--accent, var(--green)));
}
@media (hover: hover) {
  .tl-card.is-chosen .btn:hover,
  .tl-card.is-chosen .btn.primary:hover {
    filter: brightness(1.08);
    background: var(--cta-ink, var(--accent-ink, #fff));
    color: var(--cta, var(--accent, var(--green)));
  }
}

/* ---- form ----------------------------------------------------------------
   A field is a label and a control. The label is always present and always
   above: a placeholder is not a label, it disappears the moment somebody
   starts typing, and that is when they most need to know what the box is.
   ------------------------------------------------------------------------ */
.tl-form { display: flex; flex-direction: column; gap: 16px; }
/* Two fields to a row on anything wider than a phone: a six-field form in one
   column reads as a much longer form than it is. */
.tl-form-grid { display: grid; gap: 14px 16px; grid-template-columns: 1fr; }
@media (min-width: 620px) { .tl-form-grid { grid-template-columns: 1fr 1fr; } }
.tl-form-grid .tl-field.is-full { grid-column: 1 / -1; }

.tl-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.tl-field > label, .tl-label {
  font-size: 12.5px; font-weight: 700; color: var(--text);
  display: flex; align-items: baseline; gap: 7px;
}
.tl-label .tl-opt { font-weight: 400; color: var(--faint); font-size: 11.5px; }

.tl-field :is(input[type=text], input[type=email], input[type=tel], input[type=url],
              input[type=number], input[type=date], input:not([type]), textarea, select),
.tl-input {
  width: 100%; min-width: 0; box-sizing: border-box;
  padding: 11px 14px; font: inherit; font-size: 15px; line-height: 1.4;
  color: var(--text); background: var(--bg, transparent);
  border: 1px solid var(--line, rgba(128,128,128,.3));
  /* --r-md, not --r-sm. Standing rule 7 says a control's corner is --r-md and
     nothing else, and this said --r-sm, so the same control rendered two
     different corners depending on whether it happened to sit inside a form:
     10px on its own, 16px when the generic control rule also matched. The
     help panel's search box is the one outside a form, so it was the one that
     looked wrong. Found 21 September. */
  border-radius: var(--r-md, 14px);
  transition: border-color .18s ease, box-shadow .18s ease;
}
.tl-field textarea { resize: vertical; min-height: 92px; }
.tl-field select { appearance: none; -webkit-appearance: none; padding-right: 38px;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 19px) calc(50% + 2px), calc(100% - 14px) calc(50% + 2px);
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }
.tl-field :is(input, textarea, select):focus-visible {
  outline: none; border-color: var(--cta, var(--accent, var(--green)));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--cta, var(--accent, var(--green))) 22%, transparent);
}
.tl-field :is(input, textarea, select)[aria-invalid="true"] { border-color: #E4553F; }
.tl-field .tl-note { font-size: 12px; color: var(--faint); }
.tl-field .tl-note.is-error { color: #E4553F; }

/* A checkbox with its sentence, which is always a consent line here. */
.tl-check { display: flex; gap: 10px; align-items: flex-start;
            font-size: 13px; line-height: 1.55; color: var(--muted); }
.tl-check input { margin: 2px 0 0; flex: none; accent-color: var(--cta, var(--accent, var(--green))); }

/* ---- button --------------------------------------------------------------
   The second full copy of a component, found by the gallery rather than by
   reading: tl-system.css and webos.css each defined the whole .btn family,
   with different padding (28px against 20px) and opposite secondary styling,
   and the tracker loaded neither, so its buttons were the browser's.

   The secondary weight is accent-tinted rather than a hairline outline. Most
   buttons on these sites are the secondary one, and as a transparent pill it
   read as a disabled control next to body text.
   ------------------------------------------------------------------------ */
.btn, .tl-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 14px clamp(20px, 2vw, 28px);
  font-family: inherit; font-weight: 700; font-size: 15px; line-height: 1.2;
  text-decoration: none; cursor: pointer; border-radius: var(--r-pill, 999px);
  border: 1px solid var(--cta, var(--accent, var(--green)));
  color: var(--cta-text, var(--cta, var(--accent, var(--green))));
  background: var(--accent-soft, color-mix(in srgb, var(--cta, var(--accent, var(--green))) 10%, transparent));
  transition: transform .3s cubic-bezier(.22,.61,.36,1), background-color .25s ease,
              border-color .25s ease, color .25s ease, box-shadow .3s ease;
}
@media (hover: hover) {
  .btn:hover, .tl-btn:hover {
    background: var(--cta, var(--accent, var(--green)));
    color: var(--cta-ink, var(--accent-ink, var(--green-ink, #fff)));
    border-color: var(--cta, var(--accent, var(--green)));
    transform: translateY(-2px);
  }
}
.btn.primary, .tl-btn.primary {
  background: var(--cta, var(--accent, var(--green)));
  border-color: var(--cta, var(--accent, var(--green)));
  color: var(--cta-ink, var(--accent-ink, var(--green-ink, #fff)));
}
@media (hover: hover) {
  .btn.primary:hover, .tl-btn.primary:hover {
    filter: brightness(1.08); transform: translateY(-2px);
    color: var(--cta-ink, var(--accent-ink, var(--green-ink, #fff)));
    box-shadow: 0 10px 24px rgba(0,0,0,.18);
  }
}
/* A third weight, for the times a button genuinely should recede: a back
   link, a cancel. Opt in by name rather than by being the default.
   `.ghost` is the name the CRM and Find Your Passion had already given it. */
.btn.quiet, .btn.ghost, .tl-btn.quiet {
  background: transparent; border-color: var(--line); color: var(--text);
}
@media (hover: hover) {
  .btn.quiet:hover, .btn.ghost:hover, .tl-btn.quiet:hover {
    background: var(--bg2, var(--surface)); border-color: var(--text); color: var(--text);
  }
}
.btn:disabled, .tl-btn:disabled { opacity: .45; cursor: default; transform: none; }
.btn.wide, .tl-btn.wide { width: 100%; }
.btn:focus-visible, .tl-btn:focus-visible {
  outline: 2px solid var(--cta, var(--accent, var(--green))); outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .btn, .btn:hover, .btn.primary:hover, .tl-btn, .tl-btn:hover { transform: none; }
}

/* ---- choice --------------------------------------------------------------
   The selectable card: a radio drawn as a target big enough to hit. Written
   four times over as .pf-opt, .q-scale, .q-opts and .g-opt, each with its own
   hit area and its own idea of what "selected" looks like.
   ------------------------------------------------------------------------ */
.tl-choices { display: grid; gap: 10px;
              grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr)); }
.tl-choices.is-stacked { grid-template-columns: 1fr; }

.tl-choice {
  position: relative; display: flex; flex-direction: column; gap: 3px;
  padding: 15px 44px 15px 17px; cursor: pointer;
  background: var(--surface, var(--bg2)); color: var(--text);
  border: 1px solid var(--line, rgba(128,128,128,.3));
  border-radius: var(--r-md, 14px);
  transition: border-color .18s ease, background-color .18s ease, transform .18s ease;
}
.tl-choice input { position: absolute; opacity: 0; width: 0; height: 0; }
.tl-choice .tl-choice-t { font-weight: 700; font-size: 15px; }
.tl-choice .tl-choice-d { font-size: 13px; color: var(--muted); line-height: 1.5; }
/* The ring, always drawn, so the control reads as choosable before it is hot. */
.tl-choice::after {
  content: ''; position: absolute; top: 50%; right: 16px; transform: translateY(-50%);
  width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid var(--line, rgba(128,128,128,.4));
  transition: border-color .18s ease, box-shadow .18s ease;
}
@media (hover: hover) {
  .tl-choice:hover { border-color: var(--cta, var(--accent, var(--green))); transform: translateY(-1px); }
  .tl-choice:hover::after { border-color: var(--cta, var(--accent, var(--green))); }
}
.tl-choice:has(input:checked) {
  border-color: var(--cta, var(--accent, var(--green)));
  background: var(--accent-soft, color-mix(in srgb, var(--cta, #888) 10%, transparent));
}
.tl-choice:has(input:checked)::after {
  border-color: var(--cta, var(--accent, var(--green)));
  box-shadow: inset 0 0 0 4px var(--cta, var(--accent, var(--green)));
}
.tl-choice:has(input:focus-visible) { outline: 2px solid var(--cta, var(--accent, var(--green))); outline-offset: 2px; }
/* Without :has, the selected state still has to be visible. */
@supports not selector(:has(*)) {
  .tl-choice input:checked ~ .tl-choice-t { text-decoration: underline; }
}
@media (prefers-reduced-motion: reduce) { .tl-choice, .tl-choice:hover { transform: none; } }

/* ---- progress ------------------------------------------------------------
   A stepped form that does not say how long it is asks somebody to commit to
   an unknown number of questions.
   ------------------------------------------------------------------------ */
.tl-progress { display: flex; flex-direction: column; gap: 8px; }
.tl-progress-bar { height: 5px; border-radius: var(--r-pill, 999px);
                   background: var(--line2, rgba(128,128,128,.18)); overflow: hidden; }
.tl-progress-bar > span { display: block; height: 100%; border-radius: inherit;
                          background: var(--cta, var(--accent, var(--green)));
                          transition: width .35s cubic-bezier(.22,.61,.36,1); }
.tl-progress-text { font-size: 12px; font-weight: 700; color: var(--faint);
                    letter-spacing: .04em; }

/* ---- figures -------------------------------------------------------------
   Numbers presented as numbers. A result read as a sentence is a result
   nobody remembers.
   ------------------------------------------------------------------------ */
.tl-figures { display: grid; gap: clamp(12px, 1.4vw, 18px);
              grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr)); }
.tl-figure { display: flex; flex-direction: column; gap: 4px;
             padding: clamp(16px, 1.8vw, 22px);
             background: var(--surface, var(--bg2));
             border: 1px solid var(--line2, var(--line));
             border-radius: var(--r-md, 14px);
             border-top: 3px solid var(--tone, var(--cta, var(--accent, var(--green)))); }
.tl-figure-n { font-family: 'Outfit', system-ui, sans-serif; font-weight: 900;
               font-size: clamp(26px, 3vw, 36px); line-height: 1;
               color: var(--tone-ink, var(--tone, var(--cta, var(--accent, var(--green))))); letter-spacing: -.02em; }
.tl-figure-l { font-size: 13.5px; font-weight: 700; color: var(--text); }
.tl-figure-s { font-size: 12.5px; color: var(--faint); line-height: 1.5; }

/* ---- disclosure ----------------------------------------------------------
   Used by the Commons and wanted in several other places, so it lives here.
   ------------------------------------------------------------------------ */
.tl-fold { border-top: 1px solid var(--line2, var(--line)); }
.tl-fold:last-of-type { border-bottom: 1px solid var(--line2, var(--line)); }
.tl-fold > summary { cursor: pointer; padding: 15px 2px; font-weight: 700; font-size: 15.5px;
                     list-style: none; display: flex; align-items: center; gap: 10px; }
.tl-fold > summary::-webkit-details-marker { display: none; }
.tl-fold > summary::before { content: '+'; width: 18px; flex: none; font-weight: 400;
                             font-size: 18px; color: var(--muted); }
.tl-fold[open] > summary::before { content: '\2212'; }
.tl-fold > summary:hover { color: var(--cta-text, var(--cta)); }
.tl-fold-body { padding: 0 2px 20px 28px; }
.tl-fold-body > * { margin-top: 0; }
@media (max-width: 620px) { .tl-fold-body { padding-left: 4px; } }

/* ---- side note -----------------------------------------------------------
   Guidance that belongs beside the thing it is about rather than under it.
   ------------------------------------------------------------------------ */
.tl-aside { display: grid; gap: clamp(18px, 2.4vw, 34px); align-items: start;
            grid-template-columns: 1fr; }
@media (min-width: 900px) { .tl-aside { grid-template-columns: 1.35fr .85fr; } }
.tl-aside-note { display: flex; flex-direction: column; gap: 12px;
                 padding: clamp(18px, 2vw, 24px);
                 background: var(--bg2, var(--surface));
                 border: 1px solid var(--line2, var(--line));
                 border-radius: var(--r-md, 14px); }
.tl-aside-note h3 { margin: 0; font-size: 15px; }
.tl-aside-note ul { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 9px; }
.tl-aside-note li { font-size: 13.5px; line-height: 1.55; color: var(--muted); }
.tl-aside-note li::marker { color: var(--cta, var(--accent, var(--green))); }

/* ---- names the components answer to --------------------------------------
   Four surfaces had already invented a field: `.field` on BrandOS and Shell,
   `.referform` and `.sheet-form` on Find Your Passion. Rather than rewrite
   every form's markup in one go, those names point at the component here and
   their local rules are deleted, so there is one definition either way.

   This list is expected to shrink. A form moves to .tl-field markup when it
   is next touched, and its name comes out of here.
   ------------------------------------------------------------------------ */
.field, .referform label, .sheet-form label, .day-form label {
  display: flex; flex-direction: column; gap: 6px; min-width: 0; margin: 0;
}
.field > span, .referform label > span, .sheet-form label > span {
  font-size: 12.5px; font-weight: 700; color: var(--text);
}
.field :is(input, textarea, select),
.referform :is(input, textarea, select),
.sheet-form :is(input, textarea, select),
.day-form :is(input, textarea) {
  width: 100%; min-width: 0; box-sizing: border-box;
  padding: 11px 14px; font: inherit; font-size: 15px; line-height: 1.4;
  color: var(--text); background: var(--bg, transparent);
  border: 1px solid var(--line, rgba(128,128,128,.3));
  border-radius: var(--r-sm, 10px);
  transition: border-color .18s ease, box-shadow .18s ease;
}
.field textarea, .referform textarea, .sheet-form textarea, .day-form textarea {
  resize: vertical; min-height: 92px;
}
.field :is(input, textarea, select):focus-visible,
.referform :is(input, textarea, select):focus-visible,
.sheet-form :is(input, textarea, select):focus-visible,
.day-form :is(input, textarea):focus-visible {
  outline: none; border-color: var(--cta, var(--accent, var(--green)));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--cta, var(--accent, var(--green))) 22%, transparent);
}
.referform, .sheet-form { display: flex; flex-direction: column; gap: 16px; }
.referform .row { display: grid; gap: 14px 16px; grid-template-columns: 1fr; }
@media (min-width: 620px) { .referform .row { grid-template-columns: 1fr 1fr; } }

/* ==========================================================================
   Infographic components.

   Every design review so far has produced the same sentence about a different
   page: text-heavy, plain, dull, needs icons, needs colour, make it an
   infographic. That kept recurring because each page was composed by hand, so
   richness depended on whoever wrote it remembering to add it.

   These are the pieces that sentence is asking for. lib/page-kit.js renders
   them from data, so a section built through the kit cannot come out plain:
   it has a slot for the number, the icon and the hue whether or not anyone
   thought about them.
   ========================================================================== */

/* ---- the spectrum ---------------------------------------------------------
   Hand a list of anything this class and its children take the brand spectrum
   in order, looping after nine. Every component below reads --tone, so one
   class colours a whole section without a per-item decision.

   The ink tones, not the display tones: these land on text and on small
   marks, which WCAG asks 4.5:1 of. No literal fallbacks, deliberately: the
   first version of this carried the dark-theme values as fallbacks, and on a
   surface that had not declared the palette every one of them was used on a
   light page at 3.4:1. A missing token should be visibly missing, not quietly
   wrong. tl-system.css and webos.css both declare the set, per theme, which
   between them covers every surface.
   ------------------------------------------------------------------------ */
.tl-spectrum > *:nth-child(9n+1) { --tone: var(--tl-crimson-ink); }
.tl-spectrum > *:nth-child(9n+2) { --tone: var(--tl-red-ink); }
.tl-spectrum > *:nth-child(9n+3) { --tone: var(--tl-amber-ink); }
.tl-spectrum > *:nth-child(9n+4) { --tone: var(--tl-green-ink); }
.tl-spectrum > *:nth-child(9n+5) { --tone: var(--tl-teal-ink); }
.tl-spectrum > *:nth-child(9n+6) { --tone: var(--tl-cyan-ink); }
.tl-spectrum > *:nth-child(9n+7) { --tone: var(--tl-blue-ink); }
.tl-spectrum > *:nth-child(9n+8) { --tone: var(--tl-indigo-ink); }
.tl-spectrum > *:nth-child(9n+9) { --tone: var(--tl-violet-ink); }

/* ---- edged card -----------------------------------------------------------
   A card with its hue down the leading edge. Asked for by name: "gradient
   borders on left of the container". The edge is a gradient from the hue to
   transparent rather than a flat rule, so a column of them reads as a set
   rather than as a row of tabs.
   ------------------------------------------------------------------------ */
.tl-card.is-edged { position: relative; overflow: hidden; padding-left: clamp(20px, 2.2vw, 30px); }
.tl-card.is-edged::before {
  content: ''; position: absolute; inset: 0 auto 0 0; width: 4px;
  background: linear-gradient(180deg,
    var(--tone, var(--cta, var(--accent))) 0%,
    color-mix(in srgb, var(--tone, var(--cta, var(--accent))) 30%, transparent) 100%);
}
/* Topped instead, for a grid where a left edge would read as a margin. */
.tl-card.is-topped { position: relative; overflow: hidden; }
.tl-card.is-topped::before {
  content: ''; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: linear-gradient(90deg,
    var(--tone, var(--cta, var(--accent))) 0%,
    color-mix(in srgb, var(--tone, var(--cta, var(--accent))) 25%, transparent) 100%);
}

/* ---- icon chip ------------------------------------------------------------
   A square plate carrying an emoji, an SVG or two letters, tinted with the
   item's hue. Text-based on purpose: an icon font is another network request
   and another thing to go wrong, and two letters read at any size.
   ------------------------------------------------------------------------ */
.tl-icon {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 38px; height: 38px; border-radius: var(--r-sm, 10px);
  font-size: 17px; line-height: 1; font-weight: 800; letter-spacing: .01em;
  background: color-mix(in srgb, var(--tone, var(--cta, var(--accent))) 15%, transparent);
  color: var(--tone, var(--cta, var(--accent)));
}
.tl-icon.is-sm { width: 30px; height: 30px; font-size: 13.5px; border-radius: var(--r-xs, 8px); }
.tl-icon.is-lg { width: 48px; height: 48px; font-size: 22px; border-radius: var(--r-md, 14px); }
.tl-icon.is-solid { background: var(--tone, var(--cta, var(--accent)));
                    color: var(--cta-ink, var(--accent-ink, var(--green-ink, #fff))); }
.tl-icon.is-round { border-radius: var(--r-pill, 999px); }
/* An emoji must not be recoloured, and must not inherit the plate's weight. */
.tl-icon .emo { font-weight: 400; font-style: normal;
                font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif; }

/* ---- steps ----------------------------------------------------------------
   A numbered sequence: the six fortnights, the five days, the path. The
   number is the ornament, in the item's hue, and the rule between items is
   what makes it read as an order rather than as a list of cards.
   ------------------------------------------------------------------------ */
.tl-steps { display: grid; gap: clamp(12px, 1.4vw, 18px);
            grid-template-columns: repeat(auto-fit, minmax(var(--tl-col, 250px), 1fr)); }
.tl-steps.is-stacked { grid-template-columns: 1fr; gap: 0; }
.tl-step { position: relative; display: flex; flex-direction: column; gap: 8px;
           padding: clamp(18px, 2vw, 24px);
           background: var(--surface, var(--bg2)); border: 1px solid var(--line);
           border-radius: var(--r-md, 14px); }
.tl-steps.is-stacked .tl-step { background: transparent; border: 0;
  border-top: 1px solid var(--line); border-radius: 0;
  display: grid; grid-template-columns: 56px minmax(0, 1fr); gap: 0 16px; align-items: start; }
.tl-steps.is-stacked .tl-step:last-child { border-bottom: 1px solid var(--line); }
.tl-step-n { font-family: 'Outfit', system-ui, sans-serif; font-weight: 900;
             font-size: clamp(22px, 2.4vw, 30px); line-height: 1;
             color: var(--tone, var(--cta, var(--accent))); }
/* Two children and two columns: the number, and everything else in one body.
   The number column is a fixed width, so every row's text starts at the same
   place. It used to be auto, sized to each row's own number, so headings
   started at 59, 63 and 64 pixels down the same list; and before that the
   text was loose children of the grid, so a fourth child or a spanning rule
   put a heading underneath the number instead of beside it. */
.tl-steps.is-stacked .tl-step-n { font-size: clamp(24px, 3vw, 36px); }
.tl-step-body { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.tl-steps.is-stacked .tl-step-body { gap: 4px; }

/* A price list (the products page). One row per item: the name and what it is
   on the left, the price on the right, and a retainer note across the bottom.
   Stacked one under another, as plain stacked steps are, each app took four
   lines and left the right half of the row empty. */
/* The number sits with the name it belongs to, not in the middle of the row:
   centred, it drifted below the name on any item with a note. A narrower
   column and a matched line box put the two on one line. */
.tl-steps.is-priced .tl-step { padding-block: 18px; align-items: start;
  grid-template-columns: 40px minmax(0, 1fr); gap: 0 14px; }
.tl-steps.is-priced .tl-step-n { font-size: 26px; line-height: 1.32; }
.tl-steps.is-priced .tl-step-body { display: grid; grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 24px; row-gap: 2px; align-items: baseline; }
.tl-steps.is-priced .tl-step-body > h3 { grid-column: 1; grid-row: 1; font-size: 17px; }
.tl-steps.is-priced .tl-step-body > p { grid-column: 1; }
.tl-steps.is-priced .tl-step-when { grid-column: 2; grid-row: 1 / span 2; align-self: center;
  justify-self: end; white-space: nowrap; font-size: 15px; letter-spacing: 0; text-transform: none;
  font-weight: 700; color: var(--text, var(--ink)); }
/* The retainer note reads as another line of the same item, so it starts where
   the name and the description start. The shared style indents it behind a
   grey rule, which at this size looked like a layout fault rather than an
   aside, and cost it a line of width. */
.tl-steps.is-priced .tl-step-body > .tl-step-note { grid-column: 1 / -1; margin-top: 6px;
  border-left: 0; padding-left: 0; color: var(--muted); }
@media (max-width: 560px) {
  .tl-steps.is-priced .tl-step-when { grid-row: 1; align-self: baseline; font-size: 14px; }
}
.tl-step-when { font-size: 11.5px; font-weight: 800; letter-spacing: .1em;
                text-transform: uppercase; color: var(--faint); }
.tl-step h3, .tl-step h4 { margin: 0; font-size: 16px; }
.tl-step p { margin: 0; font-size: 14px; line-height: 1.6; color: var(--muted); }
.tl-step .tl-step-out { font-size: 13.5px; line-height: 1.55; color: var(--muted);
                        padding-top: 8px; border-top: 1px dashed var(--line2, var(--line)); }
.tl-step .tl-step-out strong { color: var(--tone, var(--text)); }

/* A standing note on a step: why a per-month price repeats, on the four
   BrandOS apps that are retainers. Left rule rather than the dashed top rule
   of tl-step-out, because it is an aside about the step rather than its
   conclusion, and the two must not read as the same kind of thing. */
.tl-step .tl-step-note { font-size: 13px; line-height: 1.55; color: var(--muted);
                         border-left: 2px solid var(--line2, var(--line));
                         padding-left: 10px; }

/* A consent row: a checkbox, and the sentence it is consenting to.
   This lived in crm.css alone, so the same markup on BrandOS had no spacing
   and the checkbox sat against its own label. Shared markup, shared rule. */
.agree { display: flex; gap: 9px; align-items: flex-start; margin: 4px 0 18px;
  font-size: 13.5px; line-height: 1.5; color: var(--muted); }
.agree input { margin-top: 3px; flex: none; }
.agree a { color: var(--cta-text, var(--cta)); }

/* Room between the fields of a form, and before the button under them. */
.tl-form .field + .field { margin-top: 14px; }
.tl-form .field + .agree { margin-top: 16px; }
.tl-form .btn { margin-top: 4px; }

/* ---- who / what / why -----------------------------------------------------
   Three short answers instead of three paragraphs. The heading is the
   question, so the copy underneath does not have to restate it.
   ------------------------------------------------------------------------ */
.tl-qa { display: grid; gap: clamp(12px, 1.6vw, 22px);
         grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.tl-qa-item { display: flex; flex-direction: column; gap: 9px; }
.tl-qa-item > h3 { margin: 0; font-size: 13px; letter-spacing: .1em;
                   text-transform: uppercase; color: var(--tone, var(--cta-text, var(--cta))); }
.tl-qa-item > p { margin: 0; font-size: 15px; line-height: 1.6; color: var(--text); }

/* ---- highlights -----------------------------------------------------------
   The band directly under a hero: what this is, in four or five marks, before
   anyone has to read a paragraph.
   ------------------------------------------------------------------------ */
.tl-highlights { display: grid; gap: clamp(10px, 1.2vw, 16px);
                 grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.tl-highlight { display: flex; gap: 13px; align-items: flex-start;
                padding: clamp(14px, 1.5vw, 18px);
                border: 1px solid var(--line); border-radius: var(--r-md, 14px);
                background: color-mix(in srgb, var(--tone, var(--cta)) 6%, transparent); }
.tl-highlight-b { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.tl-highlight-t { font-size: 14.5px; font-weight: 700; line-height: 1.35; }
.tl-highlight-d { font-size: 13px; line-height: 1.5; color: var(--muted); }

/* ---- inclusions -----------------------------------------------------------
   What a package contains, as rows rather than prose. Three columns: the
   mark, what it is, and the one word for what it does.
   ------------------------------------------------------------------------ */
/* Pills: a centred, wrapping row of short names. Matches the sectors on the
   BrandOS home page, which were a vertical list on the website audit page. */
.tl-pills { list-style: none; margin: 0 auto; padding: 0; max-width: 900px;
  display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; }
.tl-pill { padding: 11px 22px; border-radius: 999px; background: var(--bg2, var(--surface));
  border: 1px solid var(--line); color: var(--text, var(--ink)); font-size: 15px; line-height: 1.3; }

.tl-includes { list-style: none; margin: 0; padding: 0;
               display: flex; flex-direction: column; }
.tl-include { display: grid; grid-template-columns: auto 1fr auto;
              align-items: center; gap: 12px; padding: 10px 0;
              border-bottom: 1px solid var(--line2, var(--line)); }
.tl-include:last-child { border-bottom: 0; }
.tl-include-n { font-size: 14.5px; font-weight: 700; min-width: 0; }
.tl-include-d { font-size: 12.5px; color: var(--muted); display: block; font-weight: 400; }
.tl-include-v { font-size: 11px; font-weight: 800; letter-spacing: .09em;
                text-transform: uppercase; color: var(--tone, var(--faint)); white-space: nowrap; }
.tl-includes { container-type: inline-size; }
@container (max-width: 330px) {
  .tl-include { grid-template-columns: auto 1fr; }
  .tl-include-v { grid-column: 2; }
}
@supports not (container-type: inline-size) {
  @media (max-width: 560px) {
    .tl-include { grid-template-columns: auto 1fr; }
    .tl-include-v { grid-column: 2; }
  }
}

/* A choice used as a scale point: five across a row, so the label is the
   whole target and the row reads as a scale rather than as five cards. */
.tl-choice.is-compact { padding: 13px 14px; text-align: center; align-items: center; }
.tl-choice.is-compact::after { display: none; }
.tl-choice.is-compact .tl-choice-t { font-size: 13.5px; font-weight: 600; }
.tl-choice.is-compact:has(input:checked) .tl-choice-t { font-weight: 800; }
.tl-choices.is-scale { grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); }

/* ---- phone ----------------------------------------------------------------
   A country code and a number, drawn as one control.

   The two sit in a single bordered box with the rule between them, because
   they are one answer: a select beside an input, each with its own border,
   reads as two unrelated questions.

   The code is a real <select> rather than a scripted combo box. It works with
   scripting off, it is type-ahead searchable on every platform, and it is the
   control a phone already knows how to present full screen.

   Every rule below carries the .tl-field prefix as well. The field reset
   further up is `.tl-field :is(input[type=text], ..., select)`, which is
   (0,2,1): a plain `.tl-phone > select` is (0,1,1) and loses to it whatever
   the source order, which is how the first version of this lost its divider
   and its chevron and rendered as one flat box.
   ------------------------------------------------------------------------ */
.tl-phone {
  display: grid; grid-template-columns: 7.4rem minmax(0, 1fr);
  align-items: stretch; min-width: 0;
  border: 1px solid var(--line, rgba(128,128,128,.3));
  border-radius: var(--r-sm, 10px);
  background: var(--bg, transparent);
  transition: border-color .18s ease, box-shadow .18s ease;
}
.tl-phone:focus-within {
  border-color: var(--cta, var(--accent, var(--green)));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--cta, var(--accent, var(--green))) 22%, transparent);
}

.tl-field .tl-phone > select, .tl-phone > select {
  width: 100%; min-width: 0; text-overflow: ellipsis;
  margin: 0; padding: 11px 26px 11px 13px;
  font: inherit; font-size: 14px; line-height: 1.4;
  color: var(--text); cursor: pointer;
  background-color: transparent;
  border: 0; border-right: 1px solid var(--line, rgba(128,128,128,.3));
  border-radius: 0; box-shadow: none; outline: none;
  appearance: none; -webkit-appearance: none;
  /* A drawn chevron rather than gradient triangles: at 5px those were
     invisible on both themes. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23888' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-position: calc(100% - 9px) 50%;
  background-size: 10px 6px;
  background-repeat: no-repeat;
}
.tl-field .tl-phone > input, .tl-phone > input {
  width: 100%; min-width: 0; margin: 0; padding: 11px 14px;
  font: inherit; font-size: 15px; line-height: 1.4; color: var(--text);
  background: transparent; border: 0; border-radius: 0;
  box-shadow: none; outline: none;
}
.tl-field .tl-phone > select:focus-visible, .tl-phone > select:focus-visible,
.tl-field .tl-phone > input:focus-visible, .tl-phone > input:focus-visible {
  outline: 2px solid var(--cta, var(--accent)); outline-offset: -2px;
}
/* An option list is drawn by the platform and inherits nothing, so it needs
   its own colours or it is white on white on a dark theme in some browsers. */
.tl-phone > select option, .tl-phone > select optgroup {
  background: var(--bg2, var(--surface, #fff)); color: var(--text, #000);
}
@media (max-width: 380px) {
  .tl-phone { grid-template-columns: 6.2rem minmax(0, 1fr); }
  .tl-field .tl-phone > select, .tl-phone > select { padding-left: 10px; font-size: 13px; }
}

/* ---- chip ink ------------------------------------------------------------
   A tag chip is a hue at 15% over the page, with the same hue as its text.
   Both halves have to be chosen together, and until now only one of them was:
   the chip's background came from the data as a fixed rgba, which composites
   correctly over either theme, while its text colour came from the data too,
   as either a fill token (--amber, --cyan) or a literal dark-theme hex. A
   fill is not an ink. Sat on a 15% tint of itself, the group's amber measured
   2.56:1 and the works page's cyan 1.24:1.

   These are the same eight hues moved until each clears 4.5:1 on the worst
   tint it is actually used on, which means the 8% avatar grounds and the 15%
   chip grounds over all five card and page surfaces, not over white. Solved
   rather than picked; the arithmetic is in the light-theme notes.

   Nothing reads these directly. chipInk() in the bundle maps a chip's own
   background to the matching token, so a chip cannot be given ink that does
   not belong to its fill, and a row added in the CMS gets the right one
   without anybody choosing a colour.
   ------------------------------------------------------------------------ */
:root {
  --chip-crimson-ink: #DD606F;
  --chip-red-ink:     #FF5111;
  --chip-amber-ink:   #FF8C00;
  --chip-green-ink:   #00A86B;
  --chip-cyan-ink:    #00A3E0;
  --chip-blue-ink:    #4D94CA;
  --chip-shell-ink:   #F05E48;
  --chip-mint-ink:    #34C759;
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --chip-crimson-ink: #BA0016;
    --chip-red-ink:     #B73100;
    --chip-amber-ink:   #995400;
    --chip-green-ink:   #007249;
    --chip-cyan-ink:    #006C93;
    --chip-blue-ink:    #0063AD;
    --chip-shell-ink:   #C02710;
    --chip-mint-ink:    #207936;
  }
}
:root[data-theme="light"] {
  --chip-crimson-ink: #BA0016;
  --chip-red-ink:     #B73100;
  --chip-amber-ink:   #995400;
  --chip-green-ink:   #007249;
  --chip-cyan-ink:    #006C93;
  --chip-blue-ink:    #0063AD;
  --chip-shell-ink:   #C02710;
  --chip-mint-ink:    #207936;
}

/* A card that is a link.
   It inherits the page's text colour rather than the link colour, because a
   card whose every word turns accent-coloured stops reading as a card. The
   affordance is the lift and the cursor, which is what the rest of the kit
   uses. */
a.tl-card.is-door { text-decoration: none; color: inherit; display: block; }
a.tl-card.is-door:hover { transform: translateY(-2px); }
a.tl-card.is-door:focus-visible { outline: 2px solid var(--cta); outline-offset: 3px; }

/* ---- services rows (K.serviceRows) ------------------------------------
   The BrandOS home page's services list, for server-rendered pages. Two
   different designs of the same list on one website read as two companies. */
.tl-svc { border-bottom: 1px solid var(--line); }
.tl-svc-row { border-top: 1px solid var(--line); }
.tl-svc-row > summary { list-style: none; cursor: pointer; display: flex; align-items: center;
  flex-wrap: wrap; gap: 24px; padding: 32px 8px; }
.tl-svc-row > summary::-webkit-details-marker { display: none; }
.tl-svc-n { flex: none; width: 24px; font-size: 14px; font-weight: 700; color: var(--faint, var(--muted)); }
.tl-svc-t { flex: 1; min-width: min(100%, 200px); font-weight: 800; letter-spacing: -.02em;
  font-size: clamp(22px, 3vw, 30px); color: var(--text, var(--ink)); }
.tl-svc-chips { display: flex; flex-wrap: wrap; gap: 12px; }
.tl-svc-chip { border-radius: 999px; padding: 7px 16px; font-size: 13px; font-weight: 600;
  background: var(--bg2, var(--surface)); color: var(--text, var(--ink)); }
.tl-svc-arrow { flex: none; width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--line);
  display: inline-flex; align-items: center; justify-content: center; color: var(--text, var(--ink)); }
.tl-svc-arrow::before { content: "\2192"; }
.tl-svc-row[open] .tl-svc-arrow::before { content: "\2193"; }
.tl-svc-row[open] .tl-svc-t, .tl-svc-row[open] .tl-svc-n { color: var(--greent, var(--green, var(--ink))); }
.tl-svc-body { padding: 0 8px 32px 56px; max-width: 720px; }
.tl-svc-body p { margin: 0 0 14px; color: var(--muted); font-size: 15.5px; }
.tl-svc-body a { font-weight: 700; font-size: 14.5px; }
@media (max-width: 640px) {
  .tl-svc-row > summary { gap: 10px; padding: 22px 4px; }
  .tl-svc-t { flex: 1 1 calc(100% - 40px); min-width: 0; }
  .tl-svc-arrow { margin-left: auto; }
  .tl-svc-body { padding-left: 4px; }
}

/* A line icon takes the card's tone as ink on a tinted plate, where an
   initials plate would repeat the heading and an emoji would be a different
   drawing on every platform. */
.tl-icon.is-line { color: var(--tone, var(--cta, var(--accent))); }
.tl-icon.is-line .tl-line { display: block; }
.tl-icon.is-line.is-solid { color: var(--cta-ink, var(--accent-ink, #fff)); }

/* The audit chooser: a sentence, set apart from the hero's own copy without
   becoming a card. */
.tl-choose { margin: 22px 0 0; padding-left: 14px; border-left: 2px solid var(--line);
  font-size: 14.5px; line-height: 1.6; color: var(--muted); max-width: 62ch; }

/* A phrase that must not be split across two lines, such as "free 90-day
   tracker", where the break made it read as two separate offers. */
.nowrap { white-space: nowrap; }

/* ---- a caveat under a row of buttons ---------------------------------------
   Written on 21 September after the Shell homepage shipped with the sentence
   "Shell is being built and is not open yet" sitting flush against the bottom
   of the Join the waitlist button. Measured: zero pixels. The row set no
   bottom margin and the note set no top margin, so the two touched.

   It reads as a fourth line of the button rather than as a caveat about it,
   and the caveat is the more important of the two: it is the sentence that
   stops somebody expecting a product they cannot have yet.

   Defined here rather than per site because .cta-row is declared in three
   stylesheets with three different margins and the note is declared in a
   fourth, which is exactly how nobody noticed. checks/ui-standards.js fails
   the build on a row whose next element is closer than this.
   ------------------------------------------------------------------------ */
.cta-row + p,
.cta-row + .fine,
.cta-row + .note,
.cta-row + small { margin-top: 20px; }

/* ---- controls: one standard ------------------------------------------------
   Written on 18 September after a review found, on one page, a 42px select
   beside a 45px text field and a 48px button, and browser-default radio
   buttons at 13px. Adjusting these one page at a time is what had been
   happening; this is the rule, and verify/checks/ui-standards.js fails the
   build when a control on any page falls outside it.

   The rule:
     every control a finger or a pointer has to hit is at least 48px tall
     a radio or a checkbox is 22px, in the page's own accent colour
     a control's corner is --r-md, a button's is --r-pill, and nothing else
     the label of a choice is part of its hit area
   ------------------------------------------------------------------------ */
:where(.tl-form, .field, .tl-field, .referform, .sheet-form, form)
  :is(input:not([type=radio]):not([type=checkbox]):not([type=hidden]), select, textarea) {
  min-height: 48px; border-radius: var(--r-md, 14px); padding: 12px 16px; font-size: 15.5px;
}
:where(.tl-form, .field, .tl-field, form) textarea { min-height: 120px; }

/* A select must not look like a text field that does nothing: it keeps the
   platform arrow, and the room to show it. */
:where(.tl-form, .field, .tl-field, form) select {
  appearance: auto; cursor: pointer; padding-right: 40px;
}

/* Radios and checkboxes: big enough to read as a choice, and coloured by the
   page rather than by the browser. */
:where(form, .tl-form, .agree, .field, .g-opt, .tl-choice) :is(input[type=radio], input[type=checkbox]) {
  width: 22px; height: 22px; flex: none; accent-color: var(--cta, var(--accent, var(--green)));
  cursor: pointer;
}
.agree { align-items: center; gap: 12px; }
.agree input { margin-top: 0; }

/* A choice row is a target, not a line of text: the whole row is clickable,
   and it carries the same corner as every other card. */
.tl-choice, .g-opt {
  border-radius: var(--r-md, 14px); min-height: 56px; align-items: center; cursor: pointer;
}

/* A band that follows a hero sits under a heading and a line of copy, not
   under a section of its own. 72px of padding below 84px of hero read as a
   page that had lost its form: 171px of nothing between the subheading and
   the first field. */
.hero:has(+ .band) { padding-bottom: clamp(16px, 2vw, 28px); }
.hero + .band { padding-top: clamp(18px, 2.4vw, 32px); }

/* Skip to content: out of the way until it is focused, then the first thing on
   the page. Added 18 September; before it, reaching the content by keyboard
   meant tabbing through the whole header on every page. */
.tl-skip {
  position: absolute; left: 12px; top: -60px; z-index: 300;
  padding: 12px 18px; border-radius: var(--r-md, 14px);
  background: #34C759; color: #04170B;
  font-weight: 700; text-decoration: none; transition: top .15s ease;
}
.tl-skip:focus-visible, .tl-skip:focus { top: 12px; }
#main:focus { outline: none; }

/* ---- accounts and sign-in ----------------------------------------------
   One column, hairlines rather than cards, and nothing per page.

   Lives here rather than in ni.css because the account screens are not
   Natural Intelligence's: they are the estate's, mounted on the host whose
   cookie they use. When a second host takes an account, it loads this file
   already and the screens arrive dressed.

   The controls themselves are not styled here. They are inside .tl-form, so
   the controls block above owns their height, corner and accent, which is the
   whole point of there being one.
   ------------------------------------------------------------------------ */
.acct-col { max-width: 560px; }
/* A sign-in screen is not a hero. The surrounding sites set h1 at their
   landing scale, which pushed "Sign in, or start" onto two lines inside this
   column and made a utility page shout. */
.acct-col h1 { font-size: clamp(28px, 3.4vw, 38px); line-height: 1.28; }
.acct-col .lede { font-size: clamp(15px, 1.5vw, 17px); }
.acct-form { max-width: 460px; }

/* The inline refusal. Danger ink on a danger tint, never a fill under text. */
.acct-alert {
  margin: 0 0 18px; padding: 13px 16px; border-radius: var(--r-md, 14px);
  background: color-mix(in srgb, var(--red, #C80018) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--red, #C80018) 34%, transparent);
  color: var(--text, var(--ink)); font-size: 14px; line-height: 1.6;
}

/* Fine print. --faint is solved against its ground in every theme, so this
   never becomes the 3.5:1 grey that caption text drifts into. */
.acct-fine { margin: 14px 0 0; font-size: 13px; line-height: 1.6; color: var(--faint); }

.acct-rows { margin: 0 0 28px; padding: 0; border-top: 1px solid var(--line); }
.acct-row { display: flex; flex-wrap: wrap; gap: 8px 20px; align-items: baseline;
            padding: 15px 0; border-bottom: 1px solid var(--line); }
.acct-row dt { flex: none; width: 108px; margin: 0; font-size: 11px; font-weight: 700;
               letter-spacing: .1em; text-transform: uppercase; color: var(--faint); }
.acct-row dd { flex: 1 1 200px; margin: 0; font-size: 15px; color: var(--text, var(--ink)); }

.acct-chip { display: inline-block; margin: 0 6px 6px 0; padding: 5px 12px;
             border-radius: var(--r-pill, 999px); border: 1px solid var(--line);
             background: var(--bg2, var(--surface)); font-size: 12.5px; color: var(--muted); }

/* Set apart by a rule and a heading, not by a red box: the box would shout
   every time somebody opened the page to do something ordinary. */
.acct-danger { margin-top: 40px; padding-top: 24px; border-top: 1px solid var(--line); }
.acct-danger h2 { margin: 0 0 8px; font-size: 15px; line-height: 1.28; }
.acct-danger p { margin: 0 0 18px; font-size: 14px; line-height: 1.6; color: var(--muted); max-width: 60ch; }

/* The one destructive control. Outlined rather than filled, so the primary
   action on the page is still the one that is not irreversible. */
.btn.danger {
  background: transparent; color: var(--red, #C80018);
  border: 1px solid color-mix(in srgb, var(--red, #C80018) 46%, transparent);
}
@media (hover: hover) {
  .btn.danger:hover { background: color-mix(in srgb, var(--red, #C80018) 8%, transparent); }
}

/* A utility button: the one case the control standard allows under 48px.
   40px, never smaller, and only for a control beside a row of content rather
   than a control somebody came to the page to press. Used by the deliverable
   row, where a 48px pair would be taller than the row it sits in. */
.btn.small, .tl-btn.small {
  min-height: 40px; padding: 8px 16px; font-size: 13.5px;
}
