/* ShopNeuro app stylesheet: ADDITIONS ONLY to the landing's src/styles.css (ADR 0003).
   Served at /assets/app.css, after /assets/styles.css, on pages whose body has class="app".

   Every selector carries an app-* class or is scoped under body.app (the .app class), and :root declares
   only --app-* tokens. No landing token or class is redefined: under .app the app adds only states the
   landing lacks, such as .btn:disabled. test/app-ui.test.ts checks every rule.

   Design: docs/design/v2, variant A "Arrival" (approved by the owner on 2026-09-27). System: system.md; screens:
   screens.md. A's own parts are variant-a.css under the names of system.md 0.1 (va-* classes are app-* classes,
   --va-* tokens are --app-* ones); the rest is screens/screens.css. The wave 4 components (drop 2) bring their
   rules with their tickets. */

/* ------------------------------------------------------------------ tokens */
:root {
  /* Colour (system.md 1.2; contrast measured, WCAG 2.x). A's --va-muted, --va-control, --va-accent, --va-link,
     --va-soft, --va-error and --va-error-line in brackets. */
  --app-ink-muted: #5f6b72;          /* [--va-muted] tertiary text on light. 5.5:1 on white, 5.0 on --bg, 4.7 on --surface-2 */
  --app-control-border: #838e94;     /* [--va-control] field, radio and tile boundary. 3.35:1 on white, 3.07 on --bg */
  --app-teal-on-dark: #7fd3de;       /* [--va-accent] icons, accents, the checked plan and the focus ring on the stage */
  --app-link-on-dark: #9fe0e8;       /* [--va-link] text actions on the stage. 6.9:1 or more over the mesh */
  --app-soft-on-dark: #b9cbd1;       /* [--va-soft] secondary text on the stage. 5.7:1 or more over the mesh */
  --app-error-on-dark: #ffb4a3;      /* [--va-error] error text on the stage. 7.2:1 or more over the mesh */
  --app-error-line-on-dark: #ff8f7a; /* [--va-error-line] the command's invalid ring on the stage */
  --app-teal-ink: #0b6574;           /* links, text actions and info text on light. 6.7:1 on white, 5.7 on --teal-soft */
  --app-good-ink: #17704a;           /* success text. 6.1:1 on white, 5.3 on --good-soft */
  --app-bad-ink: #a63a26;            /* error text, invalid borders. 6.5:1 on white, 5.4 on --bad-soft */
  --app-mid-ink: #8a5a12;            /* warning text. 5.9:1 on white, 5.2 on --mid-soft */

  /* Type (system.md 1.3; the landing's --fs-body, --fs-small, --fs-lead and --fs-eyebrow stay) */
  --app-fs-stage: clamp(2.25rem, 4.4vw, 3.5rem); /* [.va-title] the title on the stage, 36 px on phones */
  --app-fs-band: clamp(2rem, 3.2vw, 2.5rem);     /* the title on a band (Account) */
  --app-fs-card-title: 1.375rem;                 /* 22 px: the card's heading, 20 px on phones */
  --app-fs-section: 1.125rem;                    /* 18 px: section headings, legends, alert titles */
  --app-fs-caption: .8125rem;                    /* 13 px: step states, "Detected", the command's label */

  /* Spacing (4 px base): the gap of a stack */
  --app-space-4: 16px;

  /* Layout */
  --app-bar-h: 68px;            /* [.va-bar-inner] the top bar; 60 px on phones */
  --app-w-head: 880px;          /* [.va-main] the centred head on the stage */
  --app-w-flow: 760px;          /* [.va-command] the command, the store row and the preflight card */
  --app-w-auth: 440px;          /* auth and verification cards */
  --app-w-form: 600px;          /* longer forms (Enterprise) */
  --app-w-settings: 980px;      /* settings rows on paper */
  --app-rise: 96px;             /* how far the stage's dark runs behind the rising card; 64 px on phones */

  /* Controls and surfaces */
  --app-control-h: 52px;        /* fields, selects, full-width form buttons [phone .va-go] */
  --app-control-h-sm: 40px;     /* = landing .btn-sm */
  --app-radius-control: 14px;   /* [phone .va-input] fields, selects, panels */
  --app-radius-card: 22px;      /* the white card [phone .va-urlbar, landing .scanner] */
  --app-shadow-card: 0 0 0 1px rgba(11, 26, 34, .05), 0 32px 80px -32px rgba(4, 18, 27, .55);
  --app-ring: 0 0 0 1px var(--teal), 0 0 0 5px rgba(14, 124, 143, .16); /* [phone .va-input focus] fields on white */
}

/* ------------------------------------------------------------ utilities */
.app-sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.app-i { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.app-i-dot { fill: currentColor; stroke: none; }
.app-muted { color: var(--app-ink-muted); }
.app-secondary { color: var(--ink-2); }
.app-secondary b { color: var(--ink); font-weight: 600; }
.app-small { font-size: var(--fs-small); }
.app-stack { display: grid; gap: var(--app-space-4); align-content: start; }
.app-link { color: var(--app-teal-ink); font-weight: 500; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.app-link:hover { text-decoration-thickness: 2px; }

/* The landing pads the page bottom on phones for its sticky call to action. App pages have no such bar.
   The one allowed override of a landing rule, until landing follow-up L11 scopes that padding (amendment A3). */
@media (max-width: 760px) { body.app { padding-bottom: 0; } }

/* Long unbroken strings, such as email addresses, store domains and URLs, wrap instead of widening cards and
   strips (amendment A4). overflow-wrap is inherited, so this one rule covers every app element; the landing sets
   none. Flex and grid children that show a user-provided string may also shrink below their longest word. */
body.app { overflow-wrap: anywhere; }
/* Text shown verbatim (emails, domains, URLs; ui/verbatim.tsx, the fields that take them, and a failure's title and
   explanation, which carry the domain in the server's words): no contextual alternates, which in Inter draw an "x"
   between two digits as "×". The fields' own rule below sets `font: inherit`, which resets them, so the fields are
   named here with a more specific selector (e.g. the store domains text area, the tracking link's field). */
.app-verbatim, .app-command-field input, .app-input[type='email'], .app-input.app-verbatim, .app-textarea.app-verbatim { font-variant-ligatures: no-contextual; }

/* ------------------------------------------------------------------ the stage */
/* A's stage: the landing hero's dark mesh as a still frame of its own shader (/assets/mesh.webp, 12 KB),
   darkened for AA text. It fades in once on arrival; reduced motion skips it (the landing's rule).
   The stage clips what reaches past it (the mesh, and the paper .app-rise::before paints below the card) with
   `overflow: clip`, which makes no scroll container: with `hidden`, following an in-page link (an error summary's)
   scrolled the stage itself, and the title and the summary above could not be scrolled back. `hidden` stays first
   for browsers without `clip`. */
.app-stage { position: relative; isolation: isolate; min-height: 100svh; display: flex; flex-direction: column; background: var(--dark); color: var(--on-dark); overflow: hidden; overflow: clip; }
.app-stage :focus-visible { outline-color: var(--app-teal-on-dark); }
.app-stage-mesh { position: absolute; inset: 0; z-index: -1; background: url(/assets/mesh.webp) 38% 30% / cover no-repeat, var(--dark); animation: app-arrive 1.2s cubic-bezier(.2, .7, .2, 1) both; }
.app-stage-mesh::before { content: ''; position: absolute; inset: 0; background:
  radial-gradient(58% 46% at 50% 46%, rgba(4, 18, 27, .5), rgba(4, 18, 27, 0) 100%),
  linear-gradient(180deg, rgba(4, 18, 27, .74) 0%, rgba(4, 18, 27, .5) 30%, rgba(4, 18, 27, .56) 62%, rgba(4, 18, 27, .9) 100%); }
.app-stage-mesh::after { content: ''; position: absolute; inset: 0; opacity: .5; mix-blend-mode: soft-light; background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .5 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>"); }
@keyframes app-arrive { from { opacity: 0; } }
/* T2 and T3 keep the idle screen's mesh size (one viewport), so the top of every page looks like the arrival. The
   preflight island switches from T1 to T2 in the browser, so its stage is matched by its content too. */
.app-stage-flow .app-stage-mesh, .app-stage-band .app-stage-mesh, .app-stage:has(.app-flow) .app-stage-mesh { bottom: auto; height: 100svh; }

/* ----------------------------------------------------- email verification notice */
/* A slim strip at the very top of the stage: seen first, never between the title and the command. "Resend
   verification email" posts a form, and a <form> cannot sit inside A's <p>: text and form share a row div. */
.app-notice { position: relative; z-index: 21; background: rgba(255, 255, 255, .06); border-bottom: 1px solid rgba(255, 255, 255, .1); font-size: var(--fs-small); line-height: 1.5; color: var(--app-soft-on-dark); }
.app-notice-inner { display: flex; align-items: flex-start; gap: 12px; padding-block: 11px; }
.app-notice-i { margin-top: 3px; color: var(--app-teal-on-dark); }
.app-notice.is-refused .app-notice-i { color: var(--app-error-on-dark); }
.app-notice strong { color: #fff; font-weight: 600; }
.app-notice-row { flex: 1; min-width: 0; display: flex; align-items: baseline; justify-content: space-between; gap: 4px 24px; flex-wrap: wrap; }
.app-notice-row > p { flex: 0 1 auto; min-width: 0; }
.app-notice-row > form { flex: none; margin: 0; }
.app-notice-action { border: 0; background: none; padding: 0; font-weight: 600; color: var(--app-link-on-dark); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.app-notice-action:hover { color: #fff; text-decoration-thickness: 2px; }

/* ------------------------------------------------------------------ top bar */
/* The landing header in its unscrolled state: on the dark, the navigation on the right, one pill at the end. */
.app-bar { position: relative; z-index: 20; flex: none; }
.app-bar-inner { height: var(--app-bar-h); display: flex; align-items: center; gap: 20px; }
.app-bar .wordmark { color: #fff; border-radius: 6px; }
.app-nav { margin-left: auto; display: flex; align-items: center; gap: 4px; }
.app-nav-link { display: inline-flex; align-items: center; height: 38px; padding: 0 14px; border-radius: 999px; font-size: var(--fs-small); font-weight: 500; color: var(--app-soft-on-dark); text-decoration: none; transition: color .2s, background .2s; }
.app-nav-link:hover { color: #fff; background: rgba(255, 255, 255, .07); }
.app-nav-link[aria-current='page'] { color: #fff; font-weight: 600; background: rgba(255, 255, 255, .12); }
.app-bar-link { margin-left: auto; display: inline-flex; align-items: center; height: 40px; padding: 0 18px; border-radius: 999px; border: 1px solid rgba(255, 255, 255, .24); color: var(--on-dark); font-size: var(--fs-small); font-weight: 600; text-decoration: none; transition: border-color .2s; }
.app-bar-link:hover { border-color: rgba(255, 255, 255, .55); }

/* The account menu: the workspace, the email and Log out in one native <details>. Its <summary> is A's account
   button, announced as an expandable button; the panel is A's menu. */
.app-account { position: relative; padding-left: 20px; border-left: 1px solid rgba(255, 255, 255, .14); }
.app-account-btn { display: inline-flex; align-items: center; gap: 10px; height: 40px; padding: 0 12px 0 6px; border-radius: 999px; border: 1px solid rgba(255, 255, 255, .22); background: rgba(255, 255, 255, .05); color: var(--on-dark); font-size: var(--fs-small); font-weight: 500; list-style: none; cursor: pointer; transition: border-color .2s, background .2s; }
.app-account-btn::-webkit-details-marker { display: none; }
.app-account-btn:hover, .app-account[open] > .app-account-btn { border-color: rgba(255, 255, 255, .5); background: rgba(255, 255, 255, .09); }
.app-avatar { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; flex: none; background: var(--app-teal-on-dark); color: var(--dark); font-size: .8125rem; font-weight: 700; }
.app-chevron { width: 14px; height: 14px; color: var(--app-soft-on-dark); transition: transform .2s; }
.app-account[open] .app-chevron { transform: rotate(180deg); }
.app-account-menu { position: absolute; right: 0; top: calc(100% + 10px); width: 264px; padding: 6px; background: #fff; color: var(--ink); border-radius: 14px; box-shadow: 0 0 0 1px rgba(11, 26, 34, .06), var(--shadow-lg); }
.app-menu-head { display: grid; gap: 1px; padding: 10px 12px 12px; font-size: var(--fs-small); line-height: 1.45; }
.app-menu-head strong { font-weight: 600; color: var(--ink); }
.app-menu-head > span { color: var(--app-ink-muted); text-wrap: pretty; }
.app-account-menu .app-menu-head { border-bottom: 1px solid var(--line); margin-bottom: 6px; }
.app-menu-item { display: flex; align-items: center; width: 100%; height: 44px; padding: 0 12px; border: 0; border-radius: 10px; background: none; font-size: var(--fs-small); font-weight: 500; text-align: left; color: var(--ink); }
.app-menu-item:hover { background: var(--surface-2); }
.app-account-menu form, .app-sheet form { margin: 0; }
.app-account-menu :focus-visible, .app-sheet :focus-visible { outline-color: var(--teal); }

/* Phones: "Menu", also a <details>. A's sheet, but in the page flow: opening it pushes the page down instead of
   covering it, so keyboard focus never lands behind it (WCAG 2.4.11) and no script is needed to close it. */
.app-sheet-disclosure { display: none; }
.app-menu-btn { display: inline-flex; align-items: center; gap: 8px; height: 40px; padding: 0 16px 0 13px; border-radius: 999px; border: 1px solid rgba(255, 255, 255, .24); background: rgba(255, 255, 255, .05); color: var(--on-dark); font-size: var(--fs-small); font-weight: 600; list-style: none; cursor: pointer; }
.app-menu-btn::-webkit-details-marker { display: none; }
.app-sheet { padding: 8px; background: #fff; color: var(--ink); border-radius: 18px; box-shadow: var(--shadow-lg); }
.app-sheet-nav { display: grid; gap: 2px; }
.app-sheet-nav a { display: flex; align-items: center; height: 48px; padding: 0 14px; border-radius: 12px; font-weight: 500; color: var(--ink-2); text-decoration: none; }
.app-sheet-nav a[aria-current='page'] { color: var(--ink); font-weight: 600; background: var(--surface-2); }
.app-sheet-meta { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 12px; margin-top: 8px; padding: 14px 6px 6px; border-top: 1px solid var(--line); }
.app-sheet-meta .app-menu-head { padding: 0; }

/* ------------------------------------------------------------------ T1: the arrival */
.app-arrival { width: min(var(--app-w-head), 100% - 32px); margin-inline: auto; padding: clamp(56px, 13vh, 136px) 0 72px; display: flex; flex-direction: column; align-items: center; text-align: center; }
.app-stage-title { font-size: var(--app-fs-stage); line-height: 1.04; letter-spacing: -0.035em; font-weight: 650; color: #fff; }
.app-stage-lead { margin-top: 16px; max-width: 62ch; font-size: var(--fs-lead); line-height: 1.5; color: var(--app-soft-on-dark); }
.app-command-form { width: 100%; margin-top: 40px; display: flex; flex-direction: column; align-items: center; }

/* The command: the landing's white card and pill bar, with a visible label inside the pill. */
.app-command { width: 100%; max-width: var(--app-w-flow); }
.app-command-bar { display: flex; align-items: center; gap: 12px; height: 76px; padding: 8px 8px 8px 24px; background: #fff; color: var(--ink); border-radius: 999px; text-align: left; box-shadow: 0 0 0 1px rgba(255, 255, 255, .12), 0 28px 60px -28px rgba(0, 0, 0, .75); transition: box-shadow .2s; }
.app-command-bar:hover { box-shadow: 0 0 0 1px rgba(255, 255, 255, .35), 0 30px 70px -26px rgba(0, 0, 0, .8); }
.app-command-input { flex: 1; min-width: 0; display: flex; align-items: center; gap: 14px; cursor: text; }
.app-command-globe { width: 20px; height: 20px; color: var(--app-ink-muted); }
.app-command-field { flex: 1; min-width: 0; display: grid; gap: 1px; }
.app-command-field label { font-size: var(--app-fs-caption); font-weight: 600; line-height: 1.3; color: var(--ink-2); cursor: text; }
.app-command-field input { width: 100%; min-width: 0; height: 28px; border: 0; padding: 0; background: transparent; font-size: 1.125rem; color: var(--ink); outline: none; }
.app-command-field input::placeholder { color: var(--app-ink-muted); opacity: 1; }
.app-command-go { flex: none; height: 60px; padding: 0 30px; }
.app-stage .app-command-go:focus-visible { outline: 2px solid var(--teal); outline-offset: 3px; }
.app-command.is-invalid .app-command-bar { box-shadow: 0 0 0 2px var(--app-error-line-on-dark), 0 28px 60px -28px rgba(0, 0, 0, .75); }
/* Focus wins over the invalid look; the error text stays. */
.app-command-bar:has(input:focus-visible), .app-command.is-invalid .app-command-bar:has(input:focus-visible) { box-shadow: 0 0 0 3px var(--app-teal-on-dark), 0 0 0 9px rgba(127, 211, 222, .2), 0 30px 70px -26px rgba(0, 0, 0, .8); }
.app-command-error { display: flex; align-items: flex-start; gap: 8px; margin-top: 12px; padding-left: 26px; font-size: var(--fs-small); font-weight: 500; color: var(--app-error-on-dark); text-align: left; }
.app-command-error .app-i { margin-top: 3px; }

/* Three facts, as in the landing hero: a check and two or three words each. */
.app-facts { list-style: none; margin: 20px 0 0; padding: 0; display: flex; flex-wrap: wrap; justify-content: center; gap: 8px 24px; font-size: var(--fs-small); color: var(--app-soft-on-dark); }
.app-facts li { display: inline-flex; align-items: center; gap: 8px; }
.app-facts .app-i { color: var(--app-teal-on-dark); }

/* The plan on the stage: visible and changeable, but small. The landing's pricing chips on dark, with its ring. */
.app-plan-dark { width: 100%; min-width: 0; margin: 52px 0 0; padding: 0; border: 0; display: flex; flex-direction: column; align-items: center; }
.app-plan-dark legend { padding: 0; margin: 0 auto 14px; font-size: var(--fs-small); font-weight: 600; color: #fff; }
.app-plan-dark-options { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
.app-pill { position: relative; display: inline-flex; align-items: center; gap: 12px; height: 48px; padding: 0 18px 0 14px; border-radius: 999px; border: 1px solid rgba(255, 255, 255, .22); background: rgba(4, 18, 27, .38); cursor: pointer; transition: border-color .2s, background .2s, box-shadow .2s; }
.app-pill:hover { border-color: rgba(255, 255, 255, .5); }
.app-pill input { appearance: none; -webkit-appearance: none; flex: none; display: grid; place-items: center; width: 18px; height: 18px; margin: 0; border-radius: 50%; border: 1.5px solid rgba(255, 255, 255, .62); background: transparent; cursor: pointer; }
.app-pill input::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--app-teal-on-dark); transform: scale(0); transition: transform .15s; }
.app-pill input:checked { border-color: var(--app-teal-on-dark); }
.app-pill input:checked::before { transform: scale(1); }
.app-pill input:focus-visible { outline: none; }
.app-pill:has(input:checked) { border-color: var(--app-teal-on-dark); background: rgba(127, 211, 222, .1); box-shadow: 0 0 0 1px var(--app-teal-on-dark); }
.app-pill:has(input:focus-visible) { outline: 2px solid var(--app-teal-on-dark); outline-offset: 4px; }
.app-pill-name { font-size: .9375rem; font-weight: 600; color: #fff; white-space: nowrap; }
.app-pill-price { padding-left: 12px; border-left: 1px solid rgba(255, 255, 255, .2); font-size: .9375rem; font-weight: 650; color: #fff; font-variant-numeric: tabular-nums; white-space: nowrap; }
.app-pill-price span { font-size: var(--app-fs-caption); font-weight: 500; color: var(--app-soft-on-dark); }
@media (min-width: 861px) { .app-plan-dark-options { flex-wrap: nowrap; } }

/* ------------------------------------------------------------------ T2: flow, T3: band */
/* T2: the title (and the store row) on the stage, then one white card that rises over the stage's lower edge onto
   paper. T3: a short stage with the title, then paper. */
.app-flow { width: min(var(--app-w-head), 100% - 32px); margin-inline: auto; padding: clamp(40px, 8vh, 80px) 0 72px; display: flex; flex-direction: column; }
.app-flow-head { display: flex; flex-direction: column; align-items: center; text-align: center; }
.app-flow-head .app-stage-lead { max-width: 56ch; }
/* The rising card: a wrapper whose ::before paints the paper from --app-rise below the card's top edge to the end of
   the stage (the stage clips it). Paper is the page's work surface; the dark stays the arrival. */
.app-rise { position: relative; z-index: 0; width: 100%; max-width: var(--app-w-flow); margin: 32px auto 0; }
.app-rise.is-auth { max-width: var(--app-w-auth); }
.app-rise.is-form { max-width: var(--app-w-form); }
.app-rise::before { content: ''; position: absolute; z-index: -1; top: var(--app-rise); left: -100vw; right: -100vw; bottom: -100vh; background: var(--bg); pointer-events: none; }

.app-stage-band > main { flex: 1; display: flex; flex-direction: column; }
.app-band-head { padding: clamp(28px, 5vh, 48px) 0 clamp(36px, 6vh, 56px); }
.app-band-title { font-size: var(--app-fs-band); line-height: 1.1; letter-spacing: -0.03em; font-weight: 650; color: #fff; }
.app-band-desc { margin-top: 10px; max-width: 62ch; color: var(--app-soft-on-dark); }
.app-paper { flex: 1; background: var(--bg); color: var(--ink); padding: 48px 0 88px; }
.app-paper :focus-visible, .app-card :focus-visible { outline-color: var(--teal); }

/* ------------------------------------------------------------ the store row */
/* The command, once the check started: the store on the stage with "Change". A's glass pill (the plan pills' fill
   and border), the command's width. */
.app-store-row { width: 100%; max-width: var(--app-w-flow); margin: 28px auto 0; display: flex; align-items: center; gap: 14px; min-height: 64px; padding: 10px 26px 10px 22px; border-radius: 999px; border: 1px solid rgba(255, 255, 255, .22); background: rgba(4, 18, 27, .38); text-align: left; }
.app-store-row > .app-i { width: 20px; height: 20px; color: var(--app-soft-on-dark); }
.app-store-text { flex: 1; min-width: 0; display: grid; }
.app-store-domain { font-size: 1.0625rem; font-weight: 600; line-height: 1.35; color: #fff; }
.app-store-meta { font-size: var(--fs-small); line-height: 1.45; color: var(--app-soft-on-dark); }
.app-store-change { flex: none; display: inline-flex; align-items: center; min-height: 40px; border: 0; padding: 0; background: none; font-size: var(--fs-small); font-weight: 600; color: var(--app-link-on-dark); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.app-store-change:hover { color: #fff; text-decoration-thickness: 2px; }

/* ------------------------------------------------------------------ the card */
.app-card { background: var(--surface); color: var(--ink); border-radius: var(--app-radius-card); box-shadow: var(--app-shadow-card); overflow: hidden; text-align: left; }
.app-section { padding: 28px 32px; }
.app-section + .app-section { border-top: 1px solid var(--line); }
.app-section-muted { padding-block: 18px; background: var(--surface-2); font-size: var(--fs-small); color: var(--ink-2); }
.app-card-head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px 12px; margin-bottom: 18px; }
.app-card-title { min-width: 0; font-size: var(--app-fs-card-title); line-height: 1.25; letter-spacing: -0.02em; font-weight: 650; }
.app-section-title { min-width: 0; font-size: var(--app-fs-section); line-height: 1.35; letter-spacing: -0.01em; font-weight: 600; }
.app-section-desc { margin-top: 4px; max-width: 62ch; font-size: var(--fs-small); color: var(--ink-2); }
/* Headings and paragraphs that a script focuses to announce a new state show no ring (amendment A1). */
.app :is(h1, h2, h3, p)[tabindex='-1']:focus { outline: none; }
/* A plain card on paper (settings, outbox): a hairline and a soft shadow, the landing's 18 px radius. */
.app-card-plain { border-radius: var(--radius); box-shadow: 0 0 0 1px var(--line), var(--shadow); }

/* ------------------------------------------------------------------ buttons */
/* The landing's .btn, .btn-primary, .btn-ghost, .btn-light, .btn-ghost-dark, .btn-sm, unchanged. */
.app-btn-block { width: 100%; height: var(--app-control-h); }
.app .btn:disabled, .app .btn[aria-disabled='true'] { opacity: .45; cursor: not-allowed; box-shadow: none; }
.app .btn:disabled:active, .app .btn[aria-disabled='true']:active { transform: none; }
.app-btn-busy { pointer-events: none; }
.app-btn-busy::before { content: ''; width: 16px; height: 16px; border-radius: 50%; border: 2px solid currentColor; border-top-color: transparent; animation: spin .8s linear infinite; }
/* A button whose label names a store, e.g. "Analyze acmesupply.shop": a long domain wraps inside the button. */
.app-btn-wrap { height: auto; min-height: var(--app-control-h-sm); max-width: 100%; padding-block: 8px; white-space: normal; }
/* A text action on white: A's notice action in the light palette. */
.app-textbtn { display: inline-flex; align-items: center; gap: 6px; min-height: 40px; padding: 0; border: 0; background: none; font-size: var(--fs-small); font-weight: 600; color: var(--app-teal-ink); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; white-space: nowrap; }
.app-textbtn:hover { text-decoration-thickness: 2px; }
.app-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; }
.app-actions-between { justify-content: space-between; }
.app-grow { flex: 1 1 260px; min-width: 0; }
.app-actions form { margin: 0; }

/* ------------------------------------------------------------------ forms */
/* One column as wide as the form: a long nowrap button (Resume after last successful stage) must not widen it past its
   card on a narrow phone (320–360 px). */
.app-form { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; }
.app-field { display: grid; gap: 8px; min-width: 0; align-content: start; }
.app-label-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.app-label { font-size: var(--fs-small); font-weight: 600; color: var(--ink-2); }
.app-optional { font-weight: 500; color: var(--app-ink-muted); }
.app-input, .app-select, .app-textarea { display: block; width: 100%; height: var(--app-control-h); padding: 0 16px; border: 1px solid var(--app-control-border); border-radius: var(--app-radius-control); background: var(--surface); color: var(--ink); font: inherit; font-size: 1rem; transition: border-color .15s, box-shadow .15s; }
/* A text box of several lines (drop 2): as the field, 112 px high at least, resizable vertically. */
.app-textarea { height: auto; min-height: 112px; padding: 13px 16px; line-height: 1.5; resize: vertical; }
.app-input::placeholder, .app-textarea::placeholder { color: var(--app-ink-muted); opacity: 1; }
.app-input:hover, .app-select:hover, .app-textarea:hover { border-color: var(--ink-2); }
.app-input:focus-visible, .app-select:focus-visible, .app-textarea:focus-visible { outline: none; border-color: var(--teal); box-shadow: var(--app-ring); }
.app-input[aria-invalid='true'], .app-select[aria-invalid='true'], .app-textarea[aria-invalid='true'] { border-color: var(--app-bad-ink); box-shadow: inset 0 0 0 1px var(--app-bad-ink); }
/* Focus wins over the invalid look; the error text stays. */
.app-input[aria-invalid='true']:focus-visible, .app-select[aria-invalid='true']:focus-visible, .app-textarea[aria-invalid='true']:focus-visible { border-color: var(--teal); box-shadow: var(--app-ring); }
.app-input:disabled, .app-select:disabled, .app-textarea:disabled { background: var(--surface-2); border-color: var(--line); color: var(--ink-3); cursor: not-allowed; }
.app-select { appearance: none; -webkit-appearance: none; padding-right: 44px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none' stroke='%2344535b' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4.5 6.25 3.5 3.5 3.5-3.5'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 16px center; }
.app-hint { font-size: var(--fs-small); color: var(--app-ink-muted); }
.app-field-error { display: flex; align-items: flex-start; gap: 8px; font-size: var(--fs-small); font-weight: 500; color: var(--app-bad-ink); }
.app-field-error .app-i { margin-top: 3px; }
.app-fields-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 20px; }
.app-fieldset { min-width: 0; margin: 0; padding: 0; border: 0; }
.app-fieldset > legend { padding: 0; }
.app-fieldset-intro { margin-bottom: 16px; }

/* Password: the "Show" button inside the field (it appears once its inline script runs) and the rule list. */
.app-input-wrap { position: relative; }
.app-input-wrap:has(.app-reveal:not([hidden])) .app-input { padding-right: 84px; }
.app-reveal { position: absolute; top: 6px; right: 6px; height: 40px; padding: 0 12px; border: 0; border-radius: 10px; background: none; font-size: var(--fs-small); font-weight: 600; color: var(--app-teal-ink); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.app-reveal[hidden] { display: none; }
/* Each rule is text plus an icon shape, never colour alone. */
.app-rules { list-style: none; margin: 2px 0 0; padding: 0; display: grid; gap: 6px; font-size: var(--fs-small); color: var(--ink-2); }
.app-rules li { display: flex; align-items: center; gap: 10px; }
.app-rule-i { width: 16px; height: 16px; border-radius: 50%; border: 1.5px solid var(--app-control-border); flex: none; display: grid; place-items: center; color: #fff; }
.app-rule-i .app-i { width: 10px; height: 10px; stroke-width: 2.4; }
.app-rules li.is-met { color: var(--app-good-ink); }
.app-rules li.is-met .app-rule-i { background: var(--good); border-color: var(--good); }
.app-rules li.is-unmet { color: var(--app-bad-ink); font-weight: 500; }
.app-rules li.is-unmet .app-rule-i { background: var(--app-bad-ink); border-color: var(--app-bad-ink); }
/* A checkbox in a bordered row: the whole row is the label (system.md 6.5; the standard coverage, ticket 10). */
.app-check { display: grid; grid-template-columns: 20px minmax(0, 1fr); gap: 12px; align-items: start; padding: 14px 16px; border: 1px solid var(--app-control-border); border-radius: var(--app-radius-control); background: var(--surface); cursor: pointer; transition: border-color .15s, box-shadow .15s; }
.app-check:hover { border-color: var(--ink-2); }
.app-check input { appearance: none; -webkit-appearance: none; width: 20px; height: 20px; margin: 2px 0 0; border: 1.5px solid var(--app-control-border); border-radius: 6px; background: var(--surface) no-repeat center / 14px 14px; cursor: pointer; }
.app-check input:checked { border-color: var(--ink); background-color: var(--ink); background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23fff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m3.5 8.5 3 3 6-7'/%3E%3C/svg%3E"); }
.app-check input:focus-visible { outline: none; }
.app-check:has(input:focus-visible) { border-color: var(--teal); box-shadow: var(--app-ring); }
.app-check:has(input:checked) { border-color: var(--ink); }
.app-check:has(input[aria-invalid='true']) { border-color: var(--app-bad-ink); box-shadow: inset 0 0 0 1px var(--app-bad-ink); }
/* Focus wins over the error, as on the fields above: the box keeps its ring while it is marked invalid. */
.app-check:has(input[aria-invalid='true']:focus-visible) { border-color: var(--teal); box-shadow: var(--app-ring); }
.app-check-text { font-size: var(--fs-body); line-height: 1.5; color: var(--ink); }
.app-check-text small { display: block; margin-top: 2px; font-size: var(--fs-small); color: var(--ink-2); }

/* The error summary: what went wrong, and links to the fields. Focused after a refused submit. */
.app-error-summary { display: grid; grid-template-columns: 20px minmax(0, 1fr); align-content: start; gap: 4px 12px; padding: 14px 16px; border: 1px solid rgba(166, 58, 38, .28); border-radius: var(--app-radius-control); background: var(--bad-soft); color: var(--ink); font-size: var(--fs-small); }
.app-error-summary > .app-i { width: 18px; height: 18px; margin-top: 2px; color: var(--app-bad-ink); }
.app-error-summary-title { font-size: var(--fs-body); font-weight: 600; line-height: 1.45; }
.app-error-summary ul { grid-column: 2; margin: 2px 0 0; padding-left: 18px; display: grid; gap: 2px; }
.app-error-summary a { color: var(--app-bad-ink); font-weight: 500; text-underline-offset: 3px; }
.app-error-summary:focus { outline: none; }
.app-error-summary:focus-visible { outline: 2px solid var(--teal); outline-offset: 3px; }

/* ------------------------------------------------------------ status and messages */
/* The landing's .tag plus an icon, with AA text colours. Its priority tags keep meaning finding priority. */
.app-status { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px 0 8px; border-radius: 99px; font-size: var(--fs-eyebrow); font-weight: 600; letter-spacing: .01em; white-space: nowrap; }
.app-status .app-i { width: 12px; height: 12px; stroke-width: 2.2; }
.app-status-neutral { background: var(--surface-2); color: var(--ink-2); }
.app-status-info { background: var(--teal-soft); color: var(--app-teal-ink); }
.app-status-success { background: var(--good-soft); color: var(--app-good-ink); }
.app-status-warning { background: var(--mid-soft); color: var(--app-mid-ink); }
.app-status-danger { background: var(--bad-soft); color: var(--app-bad-ink); }

/* An alert inside a card section: an icon tile, a title, a body with the reason and the actions. The card section
   is its frame; no second border. */
.app-alert { display: grid; grid-template-columns: 40px minmax(0, 1fr); align-content: start; gap: 4px 16px; }
.app-alert-icon { width: 40px; height: 40px; border-radius: 12px; display: grid; place-items: center; background: var(--surface-2); color: var(--ink-2); }
.app-alert-icon .app-i { width: 18px; height: 18px; }
.app-alert-danger .app-alert-icon { background: var(--bad-soft); color: var(--app-bad-ink); }
.app-alert-warning .app-alert-icon { background: var(--mid-soft); color: var(--app-mid-ink); }
.app-alert-success .app-alert-icon { background: var(--good-soft); color: var(--app-good-ink); }
.app-alert-info .app-alert-icon { background: var(--teal-soft); color: var(--app-teal-ink); }
.app-alert-title { align-self: center; min-width: 0; font-size: var(--app-fs-section); font-weight: 600; line-height: 1.35; letter-spacing: -0.01em; color: var(--ink); }
/* A result that heads its card ("Ready for analysis"): the card title's size. */
.app-alert-result .app-alert-title { font-size: var(--app-fs-card-title); font-weight: 650; letter-spacing: -0.02em; }
.app-alert-body { grid-column: 2; display: grid; gap: 14px; min-width: 0; font-size: var(--fs-small); color: var(--ink-2); }
.app-reason { font-weight: 500; color: var(--ink); }
.app-reason b { font-weight: 600; color: var(--app-bad-ink); }

.app-note { display: flex; align-items: flex-start; gap: 10px; min-width: 0; font-size: var(--fs-small); color: var(--ink-2); }
.app-note .app-i { margin-top: 3px; color: var(--app-ink-muted); }
.app-note b { font-weight: 600; color: var(--ink); }
.app-note-panel { padding: 12px 14px; border-radius: var(--app-radius-control); background: var(--surface-2); }
/* Ticket 42: Finding Detail's notes above its rows ("Finding restored.", the came-back note). */
.app-finding-notes { margin-bottom: var(--app-space-4); }
.app-note-good .app-i { color: var(--app-good-ink); }
/* Ticket 85 (W18.6): a closing account's note on Log in. */
.app-note-warning .app-i { color: var(--app-mid-ink); }
/* The title of a panel that opens in place, e.g. "Submit … for manual investigation". */
.app-panel-title { font-weight: 600; color: var(--ink); }
/* A confirmation next to the control that caused it, e.g. "Timezone saved." */
.app-status-line { display: inline-flex; align-items: center; gap: 8px; font-size: var(--fs-small); font-weight: 500; color: var(--app-good-ink); }

/* Confirmation cards (verified, link no longer works, check your email, done). */
.app-confirm-icon { width: 48px; height: 48px; border-radius: 14px; display: grid; place-items: center; }
.app-confirm-icon .app-i { width: 22px; height: 22px; }
.app-confirm-icon.is-good { background: var(--good-soft); color: var(--app-good-ink); }
.app-confirm-icon.is-mid { background: var(--mid-soft); color: var(--app-mid-ink); }
.app-confirm-icon.is-info { background: var(--teal-soft); color: var(--app-teal-ink); }
.app-lead { font-size: 1.0625rem; font-weight: 600; line-height: 1.5; color: var(--ink); }

/* ------------------------------------------------------------ the preflight card */
/* The three real steps: a word first; the icon shape and colour repeat it. Rows change only on server events. */
.app-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.app-step { display: flex; align-items: center; gap: 14px; min-width: 0; min-height: 48px; padding: 10px 14px; border-radius: 12px; font-size: var(--fs-body); color: var(--ink); transition: background .3s; }
.app-step-icon { width: 24px; height: 24px; border-radius: 50%; flex: none; display: grid; place-items: center; border: 1.5px solid var(--app-control-border); color: var(--app-ink-muted); font-size: .75rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.app-step-icon .app-i { width: 12px; height: 12px; stroke-width: 2.4; }
.app-step-state { margin-left: auto; padding-left: 12px; font-size: var(--app-fs-caption); font-weight: 500; color: var(--app-ink-muted); white-space: nowrap; }
.app-step.is-pending { color: var(--ink-2); }
.app-step.is-running { background: var(--teal-soft); }
.app-step.is-running .app-step-icon { border: 2px solid var(--teal); border-top-color: transparent; color: transparent; animation: spin .8s linear infinite; }
.app-step.is-running .app-step-state { color: var(--app-teal-ink); font-weight: 600; }
.app-step.is-done .app-step-icon { border: 0; background: var(--good); color: #fff; }
.app-step.is-done .app-step-state { color: var(--app-good-ink); }
.app-step.is-failed .app-step-icon { border: 0; background: var(--app-bad-ink); color: #fff; }
.app-step.is-failed .app-step-state { color: var(--app-bad-ink); font-weight: 600; }
.app-step.is-skipped { color: var(--app-ink-muted); }
.app-step.is-skipped .app-step-icon { border-style: dashed; }
.app-step.is-paused { background: var(--mid-soft); }
.app-step.is-paused .app-step-icon { border: 0; background: var(--app-mid-ink); color: #fff; }
.app-step.is-paused .app-step-state { color: var(--app-mid-ink); font-weight: 600; }

/* One segment per real step, filled by events only (decorative; the tag and the rows say it in words). */
.app-meter { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin-bottom: 14px; }
.app-meter > span { height: 6px; border-radius: 99px; background: var(--surface-2); }
.app-meter > .is-done { background: var(--teal); }
.app-meter > .is-running { background: var(--teal-soft); box-shadow: inset 0 0 0 1px rgba(14, 124, 143, .45); }
.app-meter > .is-failed { background: var(--app-bad-ink); }
.app-meter > .is-paused { background: var(--mid); }

.app-slow { display: flex; align-items: flex-start; gap: 10px; min-width: 0; margin-top: 12px; padding: 12px 14px; border-radius: var(--app-radius-control); background: var(--surface-2); font-size: var(--fs-small); color: var(--ink-2); }
.app-slow .app-i { margin-top: 3px; color: var(--ink-2); }
.app-slow strong { display: block; font-weight: 600; color: var(--ink); }
/* Without JavaScript: the "Refresh status" link under the running steps. */
.app-refresh-note { margin-top: 12px; }

/* Store details: label, value, and "Detected" or an "Unknown" tag. */
.app-details { margin: 0; display: grid; }
.app-detail { display: grid; grid-template-columns: minmax(0, 132px) minmax(0, 1fr) auto; gap: 12px; align-items: center; min-height: 52px; padding: 12px 0; border-top: 1px solid var(--line); font-size: var(--fs-small); }
.app-detail:first-child { border-top: 0; padding-top: 4px; }
.app-detail dt { color: var(--ink-2); }
.app-detail dd { margin: 0; min-width: 0; font-size: var(--fs-body); font-weight: 600; color: var(--ink); }
.app-detail dd + dd { font-size: var(--fs-small); }
.app-detail.is-unknown dd:first-of-type { font-weight: 500; color: var(--ink-2); }
/* The size while it is counted (ticket 10): the tag's clock, no spinner and no number that moves. */
.app-detail.is-pending dd:first-of-type { font-weight: 500; color: var(--ink-2); }
.app-detected { display: inline-flex; align-items: center; gap: 6px; font-size: var(--app-fs-caption); font-weight: 600; color: var(--app-good-ink); }
.app-detected .app-i { width: 12px; height: 12px; stroke-width: 2.4; }
.app-detail.is-new { animation: app-appear .3s ease-out both; }
@keyframes app-appear { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.app-details-intro { margin-bottom: 8px; }

/* The summary list of a ready setup and of settings: label, value, optional tag. */
.app-kv { margin: 0; display: grid; }
.app-kv > div { display: grid; grid-template-columns: minmax(0, 140px) minmax(0, 1fr) auto; gap: 12px; align-items: center; min-height: 48px; padding: 12px 0; border-top: 1px solid var(--line); font-size: var(--fs-small); }
.app-kv > div:first-child { border-top: 0; padding-top: 0; }
.app-kv > div:last-child { padding-bottom: 0; }
.app-kv dt { color: var(--ink-2); }
.app-kv dd { margin: 0; min-width: 0; font-size: var(--fs-body); font-weight: 600; color: var(--ink); }
.app-kv dd + dd { font-size: var(--fs-small); font-weight: 600; }
/* A value that is not there, e.g. a store's "Not chosen" market (screens.md W8.2): muted, like the list's. */
.app-kv dd.app-muted { color: var(--app-ink-muted); }

/* The plan in the card: A's plan choice on white. Three tiles on desktop, A's phone rows on phones. */
.app-plan-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.app-plan-opt { position: relative; display: grid; grid-template-columns: 18px minmax(0, 1fr); align-items: center; gap: 2px 12px; min-height: 68px; padding: 12px 16px 12px 14px; border: 1px solid var(--app-control-border); border-radius: 16px; background: var(--surface); cursor: pointer; transition: border-color .2s, background .2s, box-shadow .2s; }
.app-plan-opt:hover { border-color: var(--ink-2); }
.app-plan-opt input { grid-row: span 2; appearance: none; -webkit-appearance: none; display: grid; place-items: center; width: 18px; height: 18px; margin: 0; border-radius: 50%; border: 1.5px solid var(--app-control-border); background: var(--surface); cursor: pointer; }
.app-plan-opt input::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--teal); transform: scale(0); transition: transform .15s; }
.app-plan-opt input:checked { border-color: var(--teal); }
.app-plan-opt input:checked::before { transform: scale(1); }
.app-plan-opt input:focus-visible { outline: none; }
.app-plan-opt:has(input:checked) { border-color: var(--teal); background: #f2f9fa; box-shadow: 0 0 0 1px var(--teal); }
.app-plan-opt:has(input:focus-visible) { outline: 2px solid var(--teal); outline-offset: 3px; }
.app-plan-name { font-size: .9375rem; font-weight: 600; line-height: 1.3; color: var(--ink); }
.app-plan-price { grid-column: 2; font-size: .9375rem; font-weight: 650; line-height: 1.3; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.app-plan-price span { font-size: var(--app-fs-caption); font-weight: 500; color: var(--app-ink-muted); }
/* The plan chosen on pricing, on a tile or a pill (the landing's "Best for you" badge style). */
.app-plan-flag { position: absolute; top: -10px; left: 14px; height: 20px; padding: 0 8px; border-radius: 99px; background: var(--app-teal-on-dark); color: var(--dark); font-size: .6875rem; font-weight: 700; line-height: 20px; white-space: nowrap; }
.app-pill .app-plan-flag { left: 18px; }
/* The checked plan's tagline under the choice: every tagline is rendered; the checked one shows, so it is right
   without JavaScript too. */
.app-plan-notes { margin-top: 12px; font-size: var(--fs-small); color: var(--ink-2); }
.app-plan-notes > p { display: none; }
.app-plan-dark-options + .app-plan-notes { margin-top: 14px; color: var(--app-soft-on-dark); }
.app-plan-grid:has(input[value='audit']:checked) + .app-plan-notes > [data-plan='audit'],
.app-plan-grid:has(input[value='growth']:checked) + .app-plan-notes > [data-plan='growth'],
.app-plan-grid:has(input[value='agency']:checked) + .app-plan-notes > [data-plan='agency'],
.app-plan-dark-options:has(input[value='audit']:checked) + .app-plan-notes > [data-plan='audit'],
.app-plan-dark-options:has(input[value='growth']:checked) + .app-plan-notes > [data-plan='growth'],
.app-plan-dark-options:has(input[value='agency']:checked) + .app-plan-notes > [data-plan='agency'] { display: block; }
/* Wave 22 (ticket 45, W22.10): Growth Monitor's billing choice (two plan tiles with a note under the price), and the price
   and charge line that follow the checked choice with no script. */
.app-plan-grid.is-two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.app-plan-sub { grid-column: 2; font-size: var(--app-fs-caption); line-height: 1.4; color: var(--app-ink-muted); }
.app-plan-opt:has(.app-plan-sub) { padding-top: 12px; padding-bottom: 12px; }
.app-interval-scope [data-interval='year'] { display: none; }
.app-interval-scope:has(#interval-year:checked) [data-interval='year'] { display: inline; }
.app-interval-scope:has(#interval-year:checked) [data-interval='month'] { display: none; }
@media (max-width: 600px) { .app-plan-grid.is-two { grid-template-columns: minmax(0, 1fr); } .app-plan-opt:has(.app-plan-sub) { min-height: 54px; padding-top: 10px; padding-bottom: 10px; } .app-plan-sub { grid-column: 2 / -1; } }
/* Wave 24 (ticket 81, W24.14; screens.css "Wave 24"): a one-column list of radio tiles for any number of options (the
   Google Analytics property choice). */
.app-plan-grid.is-list { grid-template-columns: minmax(0, 1fr); }
.app-plan-grid.is-list .app-plan-opt { min-height: 60px; }
.app-plan-grid.is-list ~ .app-hint { margin-top: 12px; }

/* Wave 23 (ticket 47, W23.17): a banner above a page's rows (the ended note, Billing's success alerts). */
.app-banner { margin-bottom: 8px; }

/* The footer of the passed state: the action and what it does. */
.app-card-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; }
.app-card-foot > .app-small { flex: 1 1 260px; min-width: 0; }

/* The standard coverage (ticket 10): the two limits as figures, the required confirmation, the contact link. */
.app-limits { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.app-limits > li { display: grid; gap: 2px; align-content: start; padding: 14px 16px; border-radius: var(--app-radius-control); background: var(--surface-2); }
.app-limits strong { font-size: var(--app-fs-card-title); font-weight: 650; line-height: 1.2; letter-spacing: -0.02em; color: var(--ink); font-variant-numeric: tabular-nums; }
.app-limits span { font-size: var(--fs-small); color: var(--ink-2); }
.app-coverage-foot { font-size: var(--fs-small); color: var(--ink-2); }
.app-kv + .app-coverage-foot { margin-top: 16px; }
/* The next step of a signed-out ready setup (ticket 11): its heading, one sentence, the two ways in. */
.app-next .app-actions { margin-top: 16px; }

/* ------------------------------------------------------------ wave 5: checkout and payment */
/* The order at the top of "Review and pay": the product and the store on the left, the price (the landing's .price
   on white) and the "Test mode" tag on the right; on phones the price goes under the product. */
.app-order { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 12px 24px; }
.app-order-item { min-width: 0; }
.app-order-store { margin-top: 4px; color: var(--ink-2); }
.app-order-price { display: grid; justify-items: end; gap: 8px; }
.app-price { display: flex; align-items: baseline; gap: 6px; white-space: nowrap; }
.app-price strong { font-size: var(--app-fs-card-title); font-weight: 650; line-height: 1.25; letter-spacing: -0.02em; color: var(--ink); font-variant-numeric: tabular-nums; }
.app-price span { font-size: var(--app-fs-caption); font-weight: 500; color: var(--app-ink-muted); }
.app-order + .app-kv { margin-top: 20px; }
@media (max-width: 520px) { .app-order-price { justify-items: start; } }
/* What the buyer is told before paying (ticket 13, UF-01 step 7): three statements, each an icon and one sentence
   with its figures in bold. Not fine print: body size, ink. */
.app-points { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.app-points > li { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 12px; align-items: start; font-size: var(--fs-body); line-height: 1.5; color: var(--ink); }
.app-points > li > .app-i { width: 18px; height: 18px; margin-top: 3px; color: var(--app-teal-ink); }
.app-points b { font-weight: 650; }
/* The ready card's next step while the store's pages are counted: the note between its sentence and its button. */
.app-next .app-note { margin-top: 12px; }
/* A busy button that leaves the app ("Pay with Stripe") drops its arrow; the spinner and the verb say it. */
.app-btn-busy > .app-i { display: none; }

/* ------------------------------------------------------------ wave 6: Google sign-in */
/* "Continue with Google" (ticket 05) is Google's button, not A's: Google's branding guidelines fix its colours (white
   fill, a 1 px #747775 stroke, #1f1f1f text), its type (Google Sans Medium, 14/20), the standard four-colour "G" at
   20 px, and 12 px before the "G" and 10 px after it. A only sets its shape and size: a full-width pill at the card's
   control height, like "Log in" under it. Hover and press are Google's (a shadow and a grey state layer). */
.app-google-btn { display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%; height: var(--app-control-h); padding: 0 12px; border: 1px solid #747775; border-radius: 999px; background: #fff; color: #1f1f1f; font-family: 'Google Sans', Roboto, Arial, sans-serif; font-size: 14px; font-weight: 500; line-height: 20px; letter-spacing: .25px; white-space: nowrap; cursor: pointer; transition: background-color .218s, box-shadow .218s; }
.app-google-btn:hover { background: #eeeeee; box-shadow: 0 1px 2px 0 rgba(60, 64, 67, .3), 0 1px 3px 1px rgba(60, 64, 67, .15); }
.app-google-btn:active { background: #e6e6e6; }
.app-google-btn:focus-visible { outline: 2px solid var(--teal); outline-offset: 3px; }
.app-google-mark { width: 20px; height: 20px; flex: none; }
/* "or" between Google and the email form: a hairline each side. */
.app-divider { display: flex; align-items: center; gap: 12px; font-size: var(--fs-small); color: var(--app-ink-muted); }
.app-divider::before, .app-divider::after { content: ''; flex: 1; height: 1px; background: var(--line); }

/* ------------------------------------------------------------ settings on paper */
.app-settings { display: grid; max-width: var(--app-w-settings); }
.app-settings-row { display: grid; grid-template-columns: minmax(0, 260px) minmax(0, 1fr); gap: 32px; align-items: start; padding: 32px 0; border-top: 1px solid var(--line); }
.app-settings-row:first-child { padding-top: 0; border-top: 0; }
.app-settings-row > .app-card { padding: 24px 28px; }
.app-list { list-style: none; margin: 0; padding: 0; display: grid; }
.app-list > li { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 48px; padding: 10px 0; border-top: 1px solid var(--line); }
.app-list > li:first-child { padding-top: 0; border-top: 0; }
.app-list > li:last-child { padding-bottom: 0; }
.app-list-title { min-width: 0; font-weight: 600; color: var(--ink); }
/* A labelled field with its button on one row; the button lines up with the control (below the label). */
.app-field-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 10px 12px; }
.app-field-row > .app-field { flex: 1 1 260px; }
.app-field-row > .btn { margin-top: calc(var(--fs-small) * 1.6 + 8px); height: var(--app-control-h); }
.app-field-row > .app-status-line { flex-basis: 100%; }
/* A button its script shows (the copy field's "Copy link"): hidden until then, over the landing's `.btn` display. */
.app-field-row > .btn[hidden] { display: none; }

/* ------------------------------------------------------------ the local email outbox (minimal) */
/* The development tools on paper (screens.md 4.9 and W6.1, the outbox and the fake Google sign-in): the page header,
   plain cards, the email text in monospace. */
.app-main { padding-block: 40px 88px; }
.app-page-head { display: grid; gap: 8px; margin-bottom: 32px; max-width: 720px; }
.app-page-title { min-width: 0; font-size: var(--app-fs-band); line-height: 1.15; letter-spacing: -0.03em; font-weight: 650; }
.app-page-desc { max-width: 62ch; color: var(--ink-2); }
.app-outbox .app-section-title { margin-bottom: 12px; }
/* The fake Google sign-in's column (wave 6, W6.1): its note and its form. */
.app-dev-column { max-width: var(--app-w-form); }
.app-pre { margin: 0; white-space: pre-wrap; font-family: var(--mono); font-size: var(--fs-small); color: var(--ink); }

/* ------------------------------------------------------------ empty state (outbox) */
.app-empty { display: grid; justify-items: start; gap: 10px; padding: 32px; border: 1px dashed var(--app-control-border); border-radius: var(--radius); background: var(--surface); }
.app-empty-icon { width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; background: var(--surface-2); color: var(--ink-2); }
.app-empty-title { font-size: var(--app-fs-section); font-weight: 600; letter-spacing: -0.01em; }
.app-empty p { max-width: 52ch; color: var(--ink-2); }

/* ------------------------------------------------------------ wave 6: the admin console */
/* docs/design/v2/screens.md W6.2, system.md 8.7; ported from screens/screens.css "wave 6" under the app's names (W6.3).
   The way in: "Admin console" in the account menu (a link among the menu's items) and in the phone sheet (a row under
   the navigation, after a hairline). The console's own sheet uses the same row for "Back to ShopNeuro". */
a.app-menu-item { text-decoration: none; }
.app-sheet-links { display: grid; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line); }
.app-sheet-links a { display: flex; align-items: center; height: 48px; padding: 0 14px; border-radius: 12px; font-weight: 500; color: var(--ink-2); text-decoration: none; }
.app-sheet-links a:hover { background: var(--surface-2); color: var(--ink); }

/* The workspace switcher (ticket 16; screens.md W9.11): in the account menu (and the phone sheet) only with more than one
   membership: the current workspace with a check, the others as buttons of one form. Names wrap; the role sits at the
   right in the muted caption. */
.app-switch { margin: 0 0 6px; padding: 0 0 6px; border-bottom: 1px solid var(--line); }
.app-switch-label { padding: 4px 12px 6px; font-size: var(--app-fs-caption); font-weight: 600; color: var(--ink-2); }
.app-switch ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.app-switch-item { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 44px; margin: 0; padding: 10px 12px; border: 0; border-radius: 10px; background: none; font: inherit; font-size: var(--fs-small); font-weight: 500; line-height: 1.4; text-align: left; color: var(--ink); }
.app-switch-item > .app-i { flex: none; width: 16px; height: 16px; color: var(--app-teal-ink); }
button.app-switch-item { padding-left: 38px; cursor: pointer; }
button.app-switch-item:hover { background: var(--surface-2); }
.app-switch-item.is-current { font-weight: 600; }
.app-switch-name { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.app-switch-role { flex: none; font-size: var(--app-fs-caption); font-weight: 500; color: var(--app-ink-muted); }
.app-sheet-switch { margin: 8px 0 0; padding: 8px 0 0; border-top: 1px solid var(--line); border-bottom: 0; }
.app-sheet-switch .app-switch-label { padding-inline: 14px; }
.app-sheet-switch .app-switch-item { min-height: 48px; padding-inline: 14px; border-radius: 12px; font-size: var(--fs-body); }
.app-sheet-switch button.app-switch-item { padding-left: 40px; }
/* A Member's stores on a member's page: checkbox rows under the legend. */
.app-store-checks { margin-top: 8px; gap: 10px; }
/* A list item's title as a link (Team's members, W9.9, system 8.8; an audit on its store's page, W9.4): the list title's weight, like the table's links. */
.app-list a.app-list-title { color: var(--app-teal-ink); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.app-list a.app-list-title:hover { text-decoration-thickness: 2px; }
/* Phones: a list item's tag goes under its lines (Team's role tags, W9.9; an audit's state, W9.4). */
@media (max-width: 520px) { .app-list > li:has(> .tag) { flex-wrap: wrap; justify-content: flex-start; } .app-list > li:has(> .tag) > div { flex: 1 1 100%; } }
/* Team invitations (ticket 17, screens.md W10.6): the invite form's stores are for a Member only, so they hide while
   "Admin" is chosen (no JavaScript needed); a pending invitation's lines, then Re-send and Cancel invitation at the right,
   under the lines below 601 px; its "Expired" tag inside a line. */
.app-invite:has(#invite-role option[value='ADMIN']:checked) .app-invite-stores { display: none; }
.app-list > li > .app-actions { flex: none; gap: 8px; }
.app-sub > .tag { margin-left: 2px; vertical-align: 1px; }
@media (max-width: 600px) { .app-list > li:has(> .app-actions) { flex-wrap: wrap; } .app-list > li:has(> .app-actions) > div { flex: 1 1 100%; } }

/* The console's bar: the wordmark with the "Admin" mark, the eight views, the admin's menu. Eight views ("Feedback"
   added in wave 16, ticket 43) need about 1,300 px, so its "Menu" takes over below 1341 px (was 1241 for seven, 1161 for
   six; the app's bar: below 861 px; screens.md W7.3, W10.9, W16.32). The page's container (1,180 px) is too narrow for
   them, so the console's bar is wider (up to 1,320 px), and no view's name or the wordmark ever wraps. A detail page marks
   its view with aria-current="true". */
.app-bar-admin .app-bar-inner { width: min(1320px, 100% - 32px); }
.app-bar-admin .app-nav a, .app-bar-admin .wordmark { white-space: nowrap; }
.app-admin-mark { flex: none; display: inline-flex; align-items: center; height: 24px; margin-left: -8px; padding: 0 9px; border: 1px solid rgba(127, 211, 222, .45); border-radius: 99px; color: var(--app-teal-on-dark); font-size: var(--fs-eyebrow); font-weight: 700; letter-spacing: .02em; }
.app-bar-admin .app-nav a[aria-current='true'] { color: #fff; font-weight: 600; background: rgba(255, 255, 255, .12); }
.app-bar-admin .app-sheet-nav a[aria-current='true'] { color: var(--ink); font-weight: 600; background: var(--surface-2); }
@media (max-width: 1340px) {
  .app-bar-admin .app-nav, .app-bar-admin .app-account { display: none; }
  .app-bar-admin .app-sheet-disclosure { display: block; }
  .app-bar-admin .app-sheet-disclosure > .app-menu-btn { position: absolute; top: calc((var(--app-bar-h) - 40px) / 2); right: 16px; }
  .app-bar-admin .app-sheet-disclosure[open] > .app-menu-btn { background: #fff; color: var(--ink); border-color: #fff; }
  .app-bar-admin .app-sheet-disclosure > .app-sheet { position: relative; margin: -4px 8px 8px; }
}
/* Wave 18 (screens.md W18.9): with nine views and more (Testers, ticket 105; Costs, ticket 83) the console's bar is "Menu"
   at every width: the same switch, applied by the bar's `is-menu` class. */
.app-bar-admin.is-menu .app-nav, .app-bar-admin.is-menu .app-account { display: none; }
.app-bar-admin.is-menu .app-sheet-disclosure { display: block; }
.app-bar-admin.is-menu .app-sheet-disclosure > .app-menu-btn { position: absolute; top: calc((var(--app-bar-h) - 40px) / 2); right: 16px; }
.app-bar-admin.is-menu .app-sheet-disclosure[open] > .app-menu-btn { background: #fff; color: var(--ink); border-color: #fff; }
.app-bar-admin.is-menu .app-sheet-disclosure > .app-sheet { position: relative; margin: -4px 8px 8px; }

/* Wave 18 (W18.9): the tester code on Review and pay, a native disclosure under the pay card, its own form (ticket 105). */
.app-tester-card { margin-top: 16px; }
.app-tester summary { display: inline-flex; align-items: center; gap: 6px; min-height: 40px; cursor: pointer; font-weight: 600; list-style: none; }
.app-tester summary::-webkit-details-marker { display: none; }
.app-tester summary .app-i { transition: transform .15s; }
.app-tester details[open] > summary .app-i { transform: rotate(180deg); }
.app-tester .app-form { margin-top: 12px; }
/* The code is typed in any case (the server reads it in upper case); the app's rule against upper-case transforms
   stands, so the field shows what was typed, with the code face's spacing. */
.app-tester .app-input.app-mono { letter-spacing: .04em; }
.app-tester-note { margin-bottom: 16px; }
/* Wave 18 (W18.11): the cost views (ticket 83): a month's table after another's, and a sentence under a table or a list. */
.app-cost-month + .app-cost-month { margin-top: 24px; }
.app-cost-foot { margin-top: 12px; }

/* A detail page's way back, above the band's title. */
.app-band-back { display: inline-flex; align-items: center; min-height: 32px; margin-bottom: 6px; font-size: var(--fs-small); font-weight: 600; color: var(--app-link-on-dark); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.app-band-back:hover { color: #fff; text-decoration-thickness: 2px; }

/* Above a list: the status filter (links; the current one has a check and A's "checked" look) or a one-line note. */
.app-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 16px; margin-bottom: 16px; }
.app-filter { display: flex; flex-wrap: wrap; gap: 8px; }
.app-filter a { display: inline-flex; align-items: center; gap: 6px; height: 40px; padding: 0 16px; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); font-size: var(--fs-small); font-weight: 500; color: var(--ink-2); text-decoration: none; transition: border-color .15s; }
.app-filter a:hover { border-color: var(--ink-3); color: var(--ink); }
.app-filter a[aria-current='page'] { border-color: var(--teal); background: #f2f9fa; box-shadow: 0 0 0 1px var(--teal); color: var(--ink); font-weight: 600; }
.app-filter .app-i { width: 14px; height: 14px; stroke-width: 2.2; color: var(--app-teal-ink); }

/* A data table in a plain card (ui/data-table.tsx). Below 961 px (where the jobs' seven columns stop fitting) every row
   becomes a block of label and value lines (the label from the cell's data-label). The table keeps explicit roles:
   a cell whose display changes loses its table semantics in some browsers. */
.app-table { width: 100%; border-collapse: collapse; font-size: var(--fs-small); color: var(--ink); }
.app-table th { padding: 12px 16px; background: var(--surface-2); font-size: var(--app-fs-caption); font-weight: 600; line-height: 1.4; color: var(--ink-2); text-align: left; white-space: nowrap; }
.app-table td { min-width: 0; padding: 14px 16px; border-top: 1px solid var(--line); line-height: 1.5; vertical-align: top; }
.app-table :is(th, td):first-child { padding-left: 24px; }
.app-table :is(th, td):last-child { padding-right: 24px; }
.app-table .app-num { text-align: right; font-variant-numeric: tabular-nums; }
/* A column of free text (a reason) takes about a third, so the short columns keep their words on one line. */
.app-table th.app-col-text { width: 30%; }
.app-table a { color: var(--app-teal-ink); font-weight: 600; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.app-table a:hover { text-decoration-thickness: 2px; }
/* A row's key link starts with hidden words ("Audit ", "Job ": .app-sr-only), whose 1 px box sits just outside the link's
   text. As an inline box the link has two fragments, and a click aimed at its first (automation's, e.g. Playwright's)
   lands on the cell. One box: the link is its text's box only. The text stays where it was. */
.app-table td.app-cell-key > a { display: inline-block; max-width: 100%; }
.app-table td .tag { margin-top: -2px; }
/* Emails and domains break at their <wbr> hints (EmailAddress), never inside a word: the column takes their width. */
.app-table td { overflow-wrap: break-word; }
.app-cell-nowrap { white-space: nowrap; }
/* A second line under a value, in a table cell or a summary list: the kind of a target, a code, a remark. */
.app-sub { display: block; margin-top: 2px; font-size: var(--fs-small); font-weight: 500; color: var(--app-ink-muted); }
.app-mono { font-family: var(--mono); font-size: var(--app-fs-caption); }
@media (max-width: 960px) {
  .app-table thead { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .app-table, .app-table tbody, .app-table tr { display: block; }
  .app-table tr { padding: 16px 20px; border-top: 1px solid var(--line); }
  .app-table tbody tr:first-child { border-top: 0; }
  .app-table td:nth-child(n) { display: grid; grid-template-columns: minmax(0, 104px) minmax(0, 1fr); gap: 0 12px; align-items: baseline; padding: 3px 0; border: 0; text-align: left; white-space: normal; }
  .app-table td::before { content: attr(data-label); color: var(--ink-2); }
  .app-table td:nth-child(n) > * { grid-column: 2; }
  .app-table td.app-cell-key { display: block; padding-bottom: 8px; font-size: var(--fs-body); }
  .app-table td.app-cell-key::before { content: none; }
  .app-table td:nth-child(n) > .tag { justify-self: start; }
}
/* Phones: a tag after a value in a stacked cell (Stores' latest audit: "Audit 3", then its state) goes under it with the
   row's full width, as the summary's and a list item's tags do (W9.4; system 8.x), since a running stage's label is long. */
@media (max-width: 520px) { .app-table td:nth-child(n) > * + .tag { grid-column: 1 / -1; margin-top: 4px; } }
/* A desktop table (from 961 px) lets text people typed take the squeeze: a reason (a free-text column) or a name in a
   link (a company) breaks anywhere, even a pasted link or a long unbroken word, so it never widens its column past the
   card. The app's own words (an action, a status) break only between words. An email or a domain breaks only at its
   <wbr> hints (EmailAddress) or after a hyphen in it, never elsewhere inside a word, and from 1081 px (where the
   console's bar shows its five views) it stays on one line: the audit log's Actor and Target at 1280. `nowrap` alone
   is not enough there: a <wbr> breaks even inside it (Chromium), so the hints are taken out of the layout. Should the
   columns' least widths ever exceed the card (a very long address), the table scrolls sideways inside its card instead
   of being cut. Stacked rows (below 961 px) break emails at their hints and other text as a last resort. */
@media (min-width: 961px) {
  .app-table td.app-col-text, .app-table td a { overflow-wrap: anywhere; }
  .app-table td .app-verbatim { overflow-wrap: break-word; }
  .app-card:has(> .app-table) { overflow-x: auto; }
}
@media (min-width: 1081px) {
  .app-table td .app-verbatim { white-space: nowrap; }
  .app-table td .app-verbatim wbr { display: none; }
}

/* Wave 10: the console's audits (ticket 39, screens.md W10.10, W10.11). An audit's page: its sections span the container
   (the stage table needs the width), each heading above its card. */
.app-settings-wide { max-width: none; }
.app-settings-wide > .app-settings-row { grid-template-columns: minmax(0, 1fr); gap: 14px; }
/* A table's total row: the same cells as the body, on --surface-2, 600. */
.app-table tfoot td { font-weight: 600; }
/* The stage table has nine columns: its headers may wrap, so it fits the card from 961 px. */
.app-stage-table th { white-space: normal; overflow-wrap: normal; }
@media (min-width: 961px) { .app-table tfoot td { background: var(--surface-2); } }
/* Nine columns need more than 961 px: the stage table stacks up to 1080 px (the same stacked rows as every table below 961).
   This block mirrors the stacked-table block of `@media (max-width: 960px)` above (and its tfoot rules below), scoped to
   .app-stage-table, with a wider label column (140 px) for the cost labels: change the two together. */
@media (min-width: 961px) and (max-width: 1080px) {
  .app-stage-table thead { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .app-stage-table, .app-stage-table tbody, .app-stage-table tfoot, .app-stage-table tr { display: block; }
  .app-stage-table tr { padding: 16px 20px; border-top: 1px solid var(--line); }
  .app-stage-table tbody tr:first-child { border-top: 0; }
  .app-stage-table tfoot tr { background: var(--surface-2); }
  .app-stage-table td:nth-child(n) { display: grid; grid-template-columns: minmax(0, 140px) minmax(0, 1fr); gap: 0 12px; align-items: baseline; padding: 3px 0; border: 0; text-align: left; white-space: normal; background: none; }
  .app-stage-table td::before { content: attr(data-label); color: var(--ink-2); }
  .app-stage-table td:nth-child(n) > * { grid-column: 2; }
  .app-stage-table td.app-cell-key { display: block; padding-bottom: 8px; font-size: var(--fs-body); }
  .app-stage-table td.app-cell-key::before { content: none; }
  .app-stage-table td:nth-child(n) > .tag { justify-self: start; }
  .app-stage-table td.app-cell-empty { display: none; }
}
@media (max-width: 960px) {
  .app-table tfoot { display: block; }
  .app-table tfoot tr { background: var(--surface-2); }
  .app-table td.app-cell-empty { display: none; }
}

/* Under a list: "Newer" and "Older" (secondary, small); "Older" stays at the right on the first page. */
.app-pager { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px; margin-top: 16px; }
.app-pager-older { margin-left: auto; }

/* A job's payload, shown once with a reason: escaped JSON in monospace on a quiet panel; long lines wrap. */
.app-code { margin: 0; padding: 16px 18px; border-radius: var(--app-radius-control); background: var(--surface-2); font-family: var(--mono); font-size: var(--app-fs-caption); line-height: 1.6; color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; }

/* An Enterprise lead's status history, newest first: the change, then who and when, then the note. */
.app-history { list-style: none; margin: 0; padding: 0; display: grid; }
.app-history > li { display: grid; gap: 2px; padding: 12px 0; border-top: 1px solid var(--line); font-size: var(--fs-small); color: var(--ink-2); }
.app-history > li:first-child { padding-top: 0; border-top: 0; }
.app-history > li:last-child { padding-bottom: 0; }
.app-history-what { font-size: var(--fs-body); font-weight: 600; color: var(--ink); }
.app-history-note { color: var(--ink); }
/* A second part inside a settings card (the lead's history under its status form). */
.app-card-part { margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--line); }
.app-card-part > .app-section-title { margin-bottom: 12px; font-size: var(--fs-body); }
/* Store domains, one per line (an Enterprise lead). */
.app-lines { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }

/* ------------------------------------------------------------ wave 11: robots.txt */
/* The copy field's two-line variant (CopyField with `lines`): the lines to add to robots.txt, read-only, in the code face. */
/* Each line stays whole (it scrolls rather than wraps); 14 px keeps "User-agent: ShopNeuroBot" on one line from 320 px. */
.app-textarea.app-copy-lines { min-height: 0; resize: none; font-family: var(--mono); font-size: .875rem; white-space: pre; overflow-wrap: normal; overflow-x: auto; }
/* The confirmed permission under the ready summary: its sentence, then "Withdraw permission". */
.app-kv + .app-robots-foot { margin-top: 16px; }
.app-robots-foot .app-actions { margin-top: 4px; }
/* Under "Need more coverage? Contact us" too, when the coverage was confirmed (design check, fix round 1). */
.app-coverage-foot + .app-robots-foot { margin-top: 16px; }
/* A line of robots.txt quoted in a sentence (Scan Progress) stays whole. */
.app-alert-body code.app-mono { white-space: nowrap; }

/* ------------------------------------------------------------ wave 14: the Change Timeline (ticket 25) */
/* Its new-issues rows use the Audit Overview's disclosure (`.app-group`, ticket 23, below). */
/* One plain card at the settings width: a muted day heading, then the day's events, newest first. */
.app-timeline-wrap { display: grid; gap: 16px; max-width: var(--app-w-settings); }
.app-timeline-card { padding: 24px 28px; }
.app-timeline-day { margin: 28px 0 8px; font-size: var(--fs-small); font-weight: 600; color: var(--ink-2); }
.app-timeline-day:first-child { margin-top: 0; }
.app-timeline { list-style: none; margin: 0; padding: 0; display: grid; }
/* An event: its time, what happened (and its detail, links, issues), its source at the right. */
.app-timeline > li { display: grid; grid-template-columns: 48px minmax(0, 1fr) auto; gap: 4px 16px; align-items: start; padding: 14px 0; border-top: 1px solid var(--line); }
.app-timeline-time { padding-top: 2px; font-size: var(--fs-small); font-weight: 600; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.app-timeline-what { font-weight: 600; color: var(--ink); }
.app-timeline-detail { margin-top: 2px; font-size: var(--fs-small); color: var(--ink-2); }
.app-timeline-links { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 4px; font-size: var(--fs-small); }
.app-timeline > li > .tag { margin-top: 2px; }
.app-group-issues > li { font-size: var(--fs-small); }
/* A finding's link outside a list (the new issues of an event) keeps the list's link look (8.8). */
.app-group-items a.app-list-title { color: var(--app-teal-ink); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.app-group-items a.app-list-title:hover { text-decoration-thickness: 2px; }
/* Past the first 100 new issues of an audit: "And 12 more in the report." under the list (ticket 25, fix round 1). */
.app-group-more { margin: 8px 0 0 26px; padding-top: 8px; border-top: 1px solid var(--line); }
@media (max-width: 600px) { .app-timeline-card { padding: 20px; } }
@media (max-width: 520px) {
  .app-timeline > li { grid-template-columns: 44px minmax(0, 1fr); }
  .app-timeline > li > .tag { grid-column: 2; justify-self: start; }
  .app-group-more { margin-left: 0; }
}

/* ------------------------------------------------------------------ tablet and phone */
@media (max-width: 860px) {
  .app-nav, .app-account { display: none; }
  .app-sheet-disclosure { display: block; }
  /* The summary sits at the right of the bar row; the sheet opens below it, in the flow. */
  .app-sheet-disclosure > .app-menu-btn { position: absolute; top: calc((var(--app-bar-h) - 40px) / 2); right: 16px; }
  .app-sheet-disclosure[open] > .app-menu-btn { background: #fff; color: var(--ink); border-color: #fff; }
  .app-sheet-disclosure > .app-sheet { position: relative; margin: -4px 8px 8px; }
  .app-settings-row { grid-template-columns: minmax(0, 1fr); gap: 14px; }
}
@media (max-width: 600px) {
  :root { --app-bar-h: 60px; --app-rise: 64px; }
  .app-notice-inner { padding-block: 10px; }
  .app-notice-row { display: block; }
  .app-notice-row > p, .app-notice-row > form { display: inline; }
  .app-notice-action { margin-left: 2px; }
  .app-arrival { padding: 36px 0 40px; }
  .app-stage-title { font-size: 2.25rem; }
  .app-stage-lead { margin-top: 12px; font-size: 1rem; }
  .app-command-form { margin-top: 28px; }
  /* The pill becomes the landing's white scanner card: the field, then a full-width button. */
  .app-command-bar { flex-direction: column; align-items: stretch; height: auto; padding: 10px; gap: 10px; border-radius: 22px; }
  .app-command-bar:has(input:focus-visible), .app-command.is-invalid .app-command-bar:has(input:focus-visible) { box-shadow: 0 0 0 1px rgba(255, 255, 255, .12), 0 28px 60px -28px rgba(0, 0, 0, .75); }
  .app-command-input { flex: none; height: 68px; padding: 0 16px; gap: 12px; border: 1px solid var(--app-control-border); border-radius: 14px; background: #fff; }
  .app-command-input:has(input:focus-visible) { border-color: var(--teal); box-shadow: var(--app-ring); }
  .app-command.is-invalid .app-command-bar { box-shadow: 0 0 0 1px rgba(255, 255, 255, .12), 0 28px 60px -28px rgba(0, 0, 0, .75); }
  .app-command.is-invalid .app-command-input { border-color: var(--app-bad-ink); box-shadow: inset 0 0 0 1px var(--app-bad-ink); }
  .app-command.is-invalid .app-command-input:has(input:focus-visible) { border-color: var(--teal); box-shadow: var(--app-ring); }
  .app-command-go { width: 100%; height: 52px; }
  .app-command-error { padding-left: 4px; }
  .app-facts { gap: 6px 18px; }
  .app-plan-dark { margin-top: 36px; align-items: stretch; }
  .app-plan-dark legend { margin: 0 0 12px; text-align: left; }
  .app-plan-dark-options { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .app-pill { height: 54px; border-radius: 16px; padding: 0 16px 0 14px; }
  .app-pill-price { margin-left: auto; padding-left: 0; border-left: 0; }
  .app-plan-dark .app-plan-notes { text-align: left; }
  .app-flow { padding: 32px 0 48px; }
  .app-flow-head .app-stage-lead { font-size: 1rem; margin-top: 12px; }
  .app-rise { margin-top: 24px; }
  .app-band-head { padding: 24px 0 32px; }
  .app-paper { padding: 32px 0 64px; }
  .app-store-row { margin-top: 24px; min-height: 0; padding: 12px 16px; gap: 12px; border-radius: 18px; }
  .app-store-row > .app-i { display: none; }
  .app-section { padding: 22px 20px; }
  .app-section-muted { padding-block: 16px; }
  .app-card-title { font-size: 1.25rem; }
  .app-fields-2 { grid-template-columns: minmax(0, 1fr); }
  .app-step { padding: 10px 12px; gap: 12px; font-size: .9375rem; }
  .app-plan-grid { grid-template-columns: minmax(0, 1fr); }
  .app-plan-opt { grid-template-columns: 18px minmax(0, 1fr) auto; min-height: 54px; padding: 0 16px 0 14px; }
  .app-plan-opt input { grid-row: auto; }
  .app-plan-price { grid-column: 3; }
  .app-plan-flag, .app-pill .app-plan-flag { left: 44px; }
  /* Full width, and a label longer than the phone is wide wraps inside the button (it keeps its height on one line). */
  .app-card-foot > .btn { width: 100%; height: auto; min-height: var(--app-control-h); padding-block: 12px; white-space: normal; text-align: center; }
  .app-settings-row { padding: 24px 0; }
  .app-settings-row > .app-card { padding: 20px; }
  .app-field-row > .btn { margin-top: 0; width: 100%; }
  .app-main { padding-block: 24px 64px; }
}
@media (max-width: 520px) {
  .app-alert-body { grid-column: 1 / -1; margin-top: 8px; }
  .app-limits { grid-template-columns: minmax(0, 1fr); }
  .app-detail { grid-template-columns: minmax(0, 1fr) auto; row-gap: 2px; }
  .app-detail dt { grid-column: 1 / -1; }
  .app-kv > div { grid-template-columns: minmax(0, 1fr) auto; row-gap: 2px; }
  .app-kv dt { grid-column: 1 / -1; }
  /* The tag goes under its value, so a long value keeps the full width (system.md 8.3). */
  .app-kv > div > dd + dd { grid-column: 1 / -1; justify-self: start; margin-top: 4px; }
}

/* ------------------------------------------------------------ wave 14: the Audit Overview (ticket 23, screens.md W14.8) */
/* "On this page": the filter's pills as links to the page's sections (none is current); the alert above them. */
.app-jump { margin-bottom: 8px; }
.app-overview-alert { margin-bottom: 16px; }
/* Coverage: the standard coverage's tiles (W4), four in a row from 861 px, with the limit as a third line. */
.app-limits small { font-size: var(--app-fs-caption); font-weight: 500; color: var(--app-ink-muted); }
@media (min-width: 861px) { .app-limits.app-coverage { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
/* A group of findings of one check and one reason: a native disclosure (no JavaScript), its summary the list row. */
.app-list > li > .app-group { flex: 1; min-width: 0; }
.app-group > summary { list-style: none; cursor: pointer; display: flex; align-items: flex-start; gap: 10px; border-radius: 8px; }
.app-group > summary::-webkit-details-marker { display: none; }
.app-group-chevron { flex: none; width: 16px; height: 16px; margin-top: 4px; color: var(--app-teal-ink); transform: rotate(-90deg); transition: transform .15s; }
.app-group[open] > summary .app-group-chevron { transform: none; }
.app-group-head { flex: 1; min-width: 0; display: grid; }
.app-group-title { font-weight: 600; color: var(--ink); }
.app-group > summary:hover .app-group-title { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.app-group > summary > .tag { flex: none; margin-top: 2px; }
.app-group-items { list-style: none; margin: 10px 0 0 26px; padding: 0; display: grid; }
.app-group-items > li { display: grid; padding: 8px 0; border-top: 1px solid var(--line); }
.app-group-items > li:last-child { padding-bottom: 0; }
/* Under Could not verify: "Show 10 of 28 pages", then the pages as plain URLs (no links). */
.app-group-pages { margin-top: 6px; }
.app-group-pages > summary { align-items: center; font-size: var(--fs-small); font-weight: 600; color: var(--app-teal-ink); }
.app-group-pages .app-group-chevron { margin-top: 0; }
.app-group-urls { margin-top: 6px; }
.app-group-urls > li { padding: 6px 0; font-size: var(--fs-small); color: var(--ink-2); }
@media (max-width: 520px) { .app-group > summary { flex-wrap: wrap; } .app-group > summary > .tag { margin-left: 26px; } .app-group-items { margin-left: 0; } }
/* ------------------------------------------------------------ wave 15: AI SEO / AEO / GEO areas on the Overview (tickets 31, 32; screens.md W15.19) */
/* The module's findings by area (crawler and content access, entity and brand clarity, product data): an h3 each. */
.app-area { display: grid; gap: 10px; padding-top: 18px; border-top: 1px solid var(--line); }
.app-small + .app-area { padding-top: 0; border-top: 0; }
.app-area-title { font-size: var(--fs-body); font-weight: 600; color: var(--ink); }
/* Not connected: the signals under Could not verify, one line each, always shown (three, no disclosure; ticket 32). */
.app-nc-items { margin-left: 0; }

/* ------------------------------------------------------------------ notifications (ticket 26, W14.26) */
/* The bell: a 40 px round link between the navigation and the account menu, like a nav pill without a word; the unread
   count on a small accent badge. Below 861 px it stays in the bar, left of "Menu". */
.app-bell { position: relative; flex: none; display: inline-grid; place-items: center; width: 40px; height: 40px; border-radius: 999px; color: var(--app-soft-on-dark); text-decoration: none; transition: color .2s, background .2s; }
.app-bell:hover { color: #fff; background: rgba(255, 255, 255, .07); }
.app-bell[aria-current='page'] { color: #fff; background: rgba(255, 255, 255, .12); }
.app-bell .app-i { width: 18px; height: 18px; }
.app-bell-count { position: absolute; top: 1px; right: -2px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px; background: var(--app-teal-on-dark); color: var(--dark); font-size: 11px; font-weight: 700; line-height: 18px; text-align: center; font-variant-numeric: tabular-nums; }
.app-nav + .app-bell { margin-left: -12px; }
@media (max-width: 860px) { .app-nav + .app-bell { margin-left: auto; margin-right: 101px; } }
/* The notification center: the list at the settings width; an unread item's title has a teal dot and 600, a read one 500. */
.app-notices-wrap { max-width: var(--app-w-settings); }
.app-notices-wrap > .app-card { padding: 24px 28px; }
.app-notices a.app-list-title { font-weight: 500; }
.app-notices > li.is-unread a.app-list-title { font-weight: 600; }
.app-notices > li.is-unread a.app-list-title::before { content: ''; display: inline-block; width: 8px; height: 8px; margin-right: 8px; border-radius: 50%; background: var(--teal); vertical-align: 2px; }
@media (max-width: 600px) { .app-notices-wrap > .app-card { padding: 20px; } }

/* ------------------------------------------------------------ wave 15: Finding Detail and the evidence viewer (ticket 24) */
/* The actions: present but not working yet, each with the reason next to them (system 7: disabled only with its reason). */
.app-finding-actions .app-actions { margin-bottom: 10px; }
.app-kv + .app-finding-actions { margin-top: 20px; }
/* What we observed: the rule's sentence at body size, a URL in it breaks anywhere. */
.app-observed { overflow-wrap: anywhere; }
/* The evidence: one item per evidence row, in the order the check recorded them, hairlines between. */
.app-evidence { list-style: none; margin: 0; padding: 0; display: grid; }
.app-evidence > li { display: grid; gap: 12px; min-width: 0; padding: 20px 0; border-top: 1px solid var(--line); }
.app-evidence > li:first-child { padding-top: 0; border-top: 0; }
.app-evidence > li:last-child { padding-bottom: 0; }
.app-evidence-title { font-size: var(--fs-body); font-weight: 600; line-height: 1.4; color: var(--ink); }
/* URL, viewport, captured: three facts on one row from 861 px; the URL takes the room and breaks anywhere. */
.app-evidence-facts { margin: 0; display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 6px 28px; }
.app-evidence-facts > div { display: grid; gap: 2px; min-width: 0; }
.app-evidence-facts dt { font-size: var(--app-fs-caption); font-weight: 500; color: var(--app-ink-muted); }
.app-evidence-facts dd { margin: 0; font-size: var(--fs-small); font-weight: 500; color: var(--ink); overflow-wrap: anywhere; }
@media (max-width: 860px) { .app-evidence-facts { grid-template-columns: minmax(0, 1fr); } }
/* Code (HTML, headers, robots.txt, sitemaps, JSON): escaped text as written, never wrapped and never run; it scrolls
   inside its panel (by keyboard too: tabindex 0, named), so the page never scrolls sideways. */
.app-evidence-code { max-height: 22rem; overflow: auto; white-space: pre; overflow-wrap: normal; }
/* A hash breaks anywhere; at 520 px and below a compact summary keeps its label above the value. */
.app-hash { overflow-wrap: anywhere; word-break: break-all; }
/* Screenshots: images, never live pages; mobile shown at its CSS width (390). */
.app-shot { margin: 0; display: grid; gap: 8px; justify-items: start; min-width: 0; }
.app-shot > a { display: block; max-width: 100%; border-radius: 10px; }
.app-shot img { display: block; max-width: 100%; height: auto; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-2); }
.app-shot-mobile img { width: 390px; }
.app-shot figcaption { font-size: var(--fs-small); color: var(--ink-2); }
/* A screenshot or the rendered HTML past its 30 days: what remains is its hash and sizes, never a broken image. */
.app-shot-gone { display: grid; grid-template-columns: 16px minmax(0, 1fr); gap: 10px; padding: 14px 16px; border: 1px dashed var(--app-control-border); border-radius: var(--app-radius-control); background: var(--surface-2); font-size: var(--fs-small); color: var(--ink-2); }
.app-shot-gone > .app-i { margin-top: 3px; color: var(--app-ink-muted); }
.app-shot-gone b { font-weight: 600; color: var(--ink); }
.app-shot-gone .app-kv { margin-top: 10px; }
.app-kv-compact > div { min-height: 0; padding: 8px 0; }
.app-kv-compact dd { font-size: var(--fs-small); font-weight: 500; }
/* A template's evidence by page, and the desktop render to compare: the findings group's disclosure (W14.4). */
.app-evidence-pages { list-style: none; margin: 20px 0 0; padding: 20px 0 0; border-top: 1px solid var(--line); display: grid; gap: 12px; }
.app-evidence-page > .app-evidence, .app-evidence-compare-body { margin: 14px 0 0 26px; padding: 14px 0 0; border-top: 1px solid var(--line); }
.app-evidence-compare { margin-top: 20px; padding-top: 20px; border-top: 1px solid var(--line); }
.app-evidence-compare-body { display: grid; gap: 12px; }
.app-evidence-more { margin-top: 16px; }
@media (max-width: 520px) { .app-evidence-page > .app-evidence, .app-evidence-compare-body { margin-left: 0; } }
/* The interpretation's four fields: a heading each, hairlines between; a field not written says so in muted text. */
.app-fields { display: grid; }
.app-fields > section { padding: 14px 0; border-top: 1px solid var(--line); }
.app-fields > section:first-child { padding-top: 0; border-top: 0; }
.app-fields > section:last-child { padding-bottom: 0; }
.app-field-title { font-size: var(--fs-body); font-weight: 600; color: var(--ink); }
.app-field-empty { margin-top: 2px; font-size: var(--fs-small); color: var(--app-ink-muted); }
/* Wave 16: AI-drafted fields (ticket 30, screens.md W16.23). */
.app-field-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.app-draft { margin-top: 6px; display: grid; gap: 8px; }
.app-draft > p, .app-draft > ol, .app-draft > ul { margin: 0; }
.app-draft ol, .app-draft ul { padding-left: 22px; display: grid; gap: 4px; }
/* A page's full URL in a list keeps the row's height and breaks anywhere. */
.app-page-urls > li { min-height: 40px; font-size: var(--fs-small); overflow-wrap: anywhere; }
/* A value of several lines (a redirect's hops): one line each. */
.app-line { display: block; overflow-wrap: anywhere; }

/* ------------------------------------------------------------ wave 16: the Action Plan (ticket 41; screens.md W16.9) */
.app-actions-form { display: contents; }
.app-actions-form > .btn { margin: 0; }
.app-readonly { margin: 0; min-height: var(--app-control-h); display: flex; align-items: center; padding: 0 16px; border: 1px solid var(--line); border-radius: var(--app-radius-control); background: var(--surface-2); color: var(--ink-2); }
.app-textarea.app-task-text { min-height: 0; line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; overflow-x: hidden; resize: vertical; }
.app-task-list > li > div > .app-sub { display: block; }

/* ------------------------------------------------------------ reduced motion, forced colours */
/* The landing already shortens every animation and transition. The two spinners stop in place; their words stay. */
@media (prefers-reduced-motion: reduce) {
  .app-step.is-running .app-step-icon, .app-btn-busy::before { animation: none; }
}

/* ------------------------------------------------------------ wave 16 part B: share links (ticket 70; screens.md W16.33, W16.35) */
.app-plain { list-style: disc; padding-left: 20px; display: block; }
.app-plain > li { display: list-item; min-height: 0; padding: 6px 0; border: 0; }
.app-card-plain > .app-note-panel, .app-card-plain > .app-status-line { margin-bottom: 14px; }
/* A group of the read-only shared report: its list open under its head (fix round 1, Spec N4). */
.app-group-static > .app-group-summary { display: flex; align-items: flex-start; gap: 10px; }
.app-group-static > .app-group-summary > .tag { flex: none; margin-top: 2px; }
.app-group-static > .app-group-items { margin-left: 0; }
/* The recipient of a share link: no app shell, no navigation, no marketing. */
.app-share-page { min-height: 100svh; display: flex; flex-direction: column; background: var(--bg); color: var(--ink); }
.app-share-page > main { flex: 1; display: flex; flex-direction: column; }
.app-share-bar { background: var(--surface); border-bottom: 1px solid var(--line); }
.app-share-bar > .container { display: flex; align-items: center; justify-content: space-between; min-height: 56px; gap: 12px; }
.app-share-brand { font-weight: 700; color: var(--ink); }
.app-share-brand i { font-style: italic; font-weight: 600; color: var(--app-teal-ink); }
.app-share-tag { font-size: var(--fs-small); color: var(--ink-2); }
.app-share-head { padding-top: 32px; padding-bottom: 8px; display: grid; gap: 12px; }
.app-share-head .app-band-title { color: var(--ink); }
.app-share-desc { margin: 0; color: var(--ink-2); }
.app-share-gone { padding-top: 80px; padding-bottom: 120px; max-width: 640px; margin: 0 auto; }
/* wave 17: the password page of a share link (ticket 71, W17.18): the same bar, one field, no metadata */
.app-share-gate { max-width: 480px; margin: 0 auto; padding-top: 72px; padding-bottom: 120px; }
.app-share-gate .app-form, .app-share-gate .app-error-summary { margin-top: 8px; }
/* wave 18: Your top priorities (ticket 37, W18.2): an ordered list of findings; the tags first, then the title, its sub
   line and why it is here. */
.app-priorities > li.app-priority { display: block; min-height: 0; }
.app-priority-tags { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.app-priority .app-sub { display: block; }
.app-priority-why { margin: 6px 0 0; }

/* ---- Wave 18, ticket 85 (screens.css "Wave 18"): the destructive action, the ghost button in the error ink (never filled red). ---- */
.btn.app-btn-danger { color: var(--app-bad-ink); border-color: var(--app-bad-ink); }
.btn.app-btn-danger:hover { background: var(--bad-soft); }

/* ---- Wave 23 (ticket 48, screens.css "Wave 23"): the buttons under a list row (Unpin). `.app-banner` is ticket 47's, above. ---- */
.app-list-actions { margin-top: 8px; }

/* ---- Wave 25 (ticket 82, W25.18): the before and after table, and the "include analytics" choice ---- */
/* The comparison sits in a card part, not in a card of its own: no extra side padding. */
.app-impact-table .app-table :is(th, td):first-child { padding-left: 0; }
.app-impact-table .app-table :is(th, td):last-child { padding-right: 0; }
.app-impact-table { overflow-x: auto; }
@media (max-width: 960px) { .app-impact-table .app-table tr { padding-left: 0; padding-right: 0; } }
/* One choice, one button (scoped to the app's body, ADR 0003): the words that follow the box, with no script. The checkbox is outside the form (the form attribute). */
body.app [data-opt='on'] { display: none; }
body.app:has(#include-analytics:checked) [data-opt='on'] { display: inline; }
body.app:has(#include-analytics:checked) [data-opt='off'] { display: none; }

/* Windows high contrast: the mesh goes, the command keeps a visible edge, a checked plan keeps its dot, and a ticked
   box is the system's own checkbox. */
@media (forced-colors: active) {
  .app-stage-mesh { display: none; }
  .app-command-bar { border: 1px solid CanvasText; }
  .app-pill input:checked::before, .app-plan-opt input:checked::before { forced-color-adjust: none; background: CanvasText; }
  .app-check input { appearance: auto; -webkit-appearance: auto; background-image: none; }
}
