/* ===========================================================================
   Sport Match (sportmatch.pl) — built on the Sport Match application's design system.

   Every colour below is copied from the app's own tokens
   (AppFrontend/ds-bundle/tokens/colors.css). Nothing here is invented: the
   accent is the logo's offset stem, the neutrals are the cool hue-258 ramp,
   and the status hues sit in the same lightness/chroma band with only the
   hue changing.

   The system's rule for type is that it splits by what the reader *does*
   with it: Space Grotesk for everything read as language, IBM Plex Mono for
   everything compared — amounts, dates, IDs, phone numbers, column headers.

   Surfaces are flat: a hairline border, rounded-xl, no shadow. Elevation
   (shadow-lg) is reserved for things that overlap.
   =========================================================================== */

/* --- Brand webfonts, self-hosted -------------------------------------------
   Vendored from the app (frontend/src/assets/fonts) so the site has no
   third-party runtime dependency and no FOUT from a cross-origin round trip.
   Both are SIL Open Font License 1.1 — see fonts/OFL-*.txt.

   Subsets: latin + latin-ext. latin-ext is required, not optional: the Polish
   copy needs ą ć ę ł ń ó ś ź ż. */

@font-face {
    font-family: 'Space Grotesk';
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url('fonts/space-grotesk-300-700-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Space Grotesk';
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url('fonts/space-grotesk-300-700-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/ibm-plex-mono-400-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/ibm-plex-mono-400-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('fonts/ibm-plex-mono-500-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('fonts/ibm-plex-mono-500-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ===========================================================================
   Tokens
   =========================================================================== */

:root {
    /* --- brand ramps, from the app's tokens/colors.css --------------------- */
    --color-slate-50:  oklch(96.5% .004 258);
    --color-slate-100: oklch(93.5% .005 258);
    --color-slate-200: oklch(90%   .006 258);
    --color-slate-300: oklch(84%   .008 258);
    --color-slate-400: oklch(72%   .012 258);
    --color-slate-500: oklch(60%   .016 258);
    --color-slate-600: oklch(50%   .02  258);
    --color-slate-700: oklch(38%   .024 258);
    --color-slate-800: oklch(30%   .028 258);
    --color-slate-900: oklch(24%   .03  258);
    --color-slate-950: oklch(19%   .03  258);

    --color-indigo-50:  oklch(97.5% .012 258);
    --color-indigo-100: oklch(94%   .032 258);
    --color-indigo-200: oklch(88%   .062 258);
    --color-indigo-300: oklch(78%   .11  258);
    --color-indigo-400: oklch(72%   .15  258);
    --color-indigo-600: oklch(52%   .19  258);
    --color-indigo-700: oklch(45%   .18  258);
    --color-indigo-800: oklch(38%   .16  258);
    --color-indigo-950: oklch(24%   .08  258);

    --color-green-100: oklch(94% .04  150);
    --color-green-400: oklch(69% .14  150);
    --color-green-700: oklch(44% .115 150);
    --color-green-950: oklch(24% .05  150);

    --color-amber-100: oklch(95% .05  85);
    --color-amber-400: oklch(76% .14  76);
    --color-amber-700: oklch(52% .13  75);
    --color-amber-950: oklch(27% .06  75);

    --color-red-100: oklch(94% .04  25);
    --color-red-400: oklch(67% .17  25);
    --color-red-600: oklch(50% .18  25);
    --color-red-700: oklch(43% .155 25);
    --color-red-950: oklch(24% .07  25);

    --color-ink:            oklch(24% .03 258);
    --color-accent:         oklch(52% .19 258);
    --color-accent-on-dark: oklch(68% .16 258);
    --surface-inverse:      oklch(21% .03 258);

    /* --- type ------------------------------------------------------------- */
    --font-sans: 'Space Grotesk', ui-sans-serif, system-ui, -apple-system, sans-serif;
    --font-mono: 'IBM Plex Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;

    --text-xs:   .75rem;
    --text-sm:   .875rem;
    --text-base: 1rem;
    --text-lg:   1.125rem;
    --text-xl:   1.25rem;
    --text-2xl:  1.5rem;
    --text-3xl:  1.875rem;
    --text-4xl:  2.25rem;

    /* The app's scale stops at 4xl because product screens never need display
       type. A landing page does, so it is extended upward on the same ratio —
       and obeys the system's own rule that the bigger a heading gets, the
       tighter it tracks. */
    --text-display: clamp(2.25rem, 1.15rem + 4.4vw, 3.5rem);
    --text-section: clamp(1.875rem, 1.55rem + 1.1vw, 2.25rem);

    /* --- shape, motion, measure ------------------------------------------- */
    --radius-md: .375rem;
    --radius-lg: .5rem;
    --radius-xl: .75rem;

    --ease-brand: cubic-bezier(.2, .7, .2, 1);
    --dur-color: 120ms;   /* colour / hover   */
    --dur-ui:    180ms;   /* switch / tab     */
    --dur-panel: 260ms;   /* dialog / toast   */

    --container:       64rem;   /* --container-5xl */
    --container-prose: 48rem;   /* --container-3xl, for legal pages */

    /* Shadows are cool and tight — ink at 5–12% alpha, never black. */
    --shadow-lg: 0 4px 8px oklch(24% .03 258 / .06), 0 20px 44px oklch(24% .03 258 / .12);

    /* --- semantic roles, named as the design system names them ------------ */
    --surface-page:   var(--color-slate-50);
    --surface-card:   #fff;
    --surface-inset:  var(--color-slate-100);
    --surface-hero:   var(--surface-inverse);
    --border-subtle:  var(--color-slate-200);
    --border-default: var(--color-slate-300);
    --text-primary:   var(--color-slate-900);
    --text-secondary: var(--color-slate-600);
    --text-tertiary:  var(--color-slate-500);
    --accent-text:    var(--color-accent);
    --accent-soft-bg: var(--color-indigo-100);
    --accent-soft-fg: var(--color-indigo-700);

    --action-primary:        var(--color-indigo-600);
    --action-primary-hover:  var(--color-indigo-700);
    --action-primary-active: var(--color-indigo-800);

    --success-bg: var(--color-green-100); --success-fg: var(--color-green-700);
    --warning-bg: var(--color-amber-100); --warning-fg: var(--color-amber-700);
    --danger-bg:  var(--color-red-100);   --danger-fg:  var(--color-red-700);
}

/* Dark theme. The app pairs every light class with a `dark:` variant, so the
   site does too. Not an inversion: the ink hero lifts to slate-900 so it still
   reads as a panel above a slate-950 page, and accent text moves to
   --accent-on-dark, which is exactly what that token exists for.

   Driven by the OS preference. The [data-theme] blocks below let a theme
   toggle override it later — matching the app's own ThemeSwitcher — without
   touching any of the styling above. */
@media (prefers-color-scheme: dark) {
    :root {
        --surface-page:   var(--color-slate-950);
        --surface-card:   var(--color-slate-900);
        --surface-inset:  var(--color-slate-800);
        --surface-hero:   var(--color-slate-900);
        --border-subtle:  var(--color-slate-800);
        --border-default: var(--color-slate-700);
        --text-primary:   var(--color-slate-100);
        --text-secondary: var(--color-slate-300);
        --text-tertiary:  var(--color-slate-400);
        --accent-text:    var(--color-accent-on-dark);
        --accent-soft-bg: var(--color-indigo-950);
        --accent-soft-fg: var(--color-indigo-400);
        --success-bg: var(--color-green-950); --success-fg: var(--color-green-400);
        --warning-bg: var(--color-amber-950); --warning-fg: var(--color-amber-400);
        --danger-bg:  var(--color-red-950);   --danger-fg:  var(--color-red-400);
    }
}

:root[data-theme="dark"] {
    --surface-page:   var(--color-slate-950);
    --surface-card:   var(--color-slate-900);
    --surface-inset:  var(--color-slate-800);
    --surface-hero:   var(--color-slate-900);
    --border-subtle:  var(--color-slate-800);
    --border-default: var(--color-slate-700);
    --text-primary:   var(--color-slate-100);
    --text-secondary: var(--color-slate-300);
    --text-tertiary:  var(--color-slate-400);
    --accent-text:    var(--color-accent-on-dark);
    --accent-soft-bg: var(--color-indigo-950);
    --accent-soft-fg: var(--color-indigo-400);
    --success-bg: var(--color-green-950); --success-fg: var(--color-green-400);
    --warning-bg: var(--color-amber-950); --warning-fg: var(--color-amber-400);
    --danger-bg:  var(--color-red-950);   --danger-fg:  var(--color-red-400);
}

:root[data-theme="light"] {
    --surface-page:   var(--color-slate-50);
    --surface-card:   #fff;
    --surface-inset:  var(--color-slate-100);
    --surface-hero:   var(--surface-inverse);
    --border-subtle:  var(--color-slate-200);
    --border-default: var(--color-slate-300);
    --text-primary:   var(--color-slate-900);
    --text-secondary: var(--color-slate-600);
    --text-tertiary:  var(--color-slate-500);
    --accent-text:    var(--color-accent);
    --accent-soft-bg: var(--color-indigo-100);
    --accent-soft-fg: var(--color-indigo-700);
    --success-bg: var(--color-green-100); --success-fg: var(--color-green-700);
    --warning-bg: var(--color-amber-100); --warning-fg: var(--color-amber-700);
    --danger-bg:  var(--color-red-100);   --danger-fg:  var(--color-red-700);
}

/* ===========================================================================
   Base
   =========================================================================== */

*, *::before, *::after {
    box-sizing: border-box;
}

body {
    margin: 0;
    font-family: var(--font-sans);
    font-size: var(--text-base);
    line-height: 1.5;
    color: var(--text-primary);
    background-color: var(--surface-page);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Space Grotesk needs negative tracking as it scales up, and headings are the
   one place the brand is emphatic about it. */
h1, h2, h3, h4 {
    margin: 0;
    font-weight: 700;
    text-wrap: balance;
}

h1 { letter-spacing: -.035em; line-height: 1.06; }
h2 { letter-spacing: -.03em;  line-height: 1.12; }
h3, h4 { letter-spacing: -.02em; }

p {
    margin: 0;
    text-wrap: pretty;
}

a {
    color: var(--accent-text);
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

/* Focus is a 3px accent ring at 32% — never a browser default outline. */
:focus-visible {
    outline: 3px solid oklch(52% .19 258 / .32);
    outline-offset: 1px;
    border-radius: var(--radius-md);
}

table {
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}

img {
    max-width: 100%;
}

/* --- the brand text roles, from the app's index.css --------------------- */

/* Small mono label above a heading. */
.eyebrow {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    line-height: 1.45;
    letter-spacing: .2em;
    text-transform: uppercase;
}

/* Table column header — same device, tracked tighter because a header row
   carries several side by side. */
.col-label {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    line-height: 1.45;
    letter-spacing: .14em;
    text-transform: uppercase;
}

/* Anything the reader compares down a column: money, dates, IDs, phones. */
.data-num {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0;
}

/* ===========================================================================
   Layout
   =========================================================================== */

.container {
    width: 100%;
    max-width: var(--container);
    margin-inline: auto;
    padding-inline: 1.5rem;
}

.section {
    padding-block: clamp(3.5rem, 8vw, 5.5rem);
}

.section-inset {
    background-color: var(--surface-inset);
}

.section-head {
    display: flex;
    flex-direction: column;
    gap: .75rem;
    margin-bottom: 2.5rem;
}

.section-head .eyebrow { color: var(--text-tertiary); }
.section-head h2 { font-size: var(--text-section); }

.section-head p {
    color: var(--text-secondary);
    font-size: var(--text-lg);
    max-width: 60ch;
}

/* ===========================================================================
   Brand lockup — Sport Match's "Pulse": a pulse line whose peak forms an M,
   the first half in ink (currentColor), the second in --chq-mark-accent —
   two sides meeting at the low point — so a tone is just a pair of CSS
   values. Per the brand's handoff rules the stroke is never split anywhere
   but that low point, never outlined, and never rotated.
   =========================================================================== */

.lockup {
    display: inline-flex;
    align-items: center;
    gap: .38em;
    font-size: 28px;
    text-decoration: none;
}

.lockup:hover { text-decoration: none; }

.lockup svg {
    width: 1em;
    height: 1em;
    display: block;
    flex: none;
}

.lockup-word {
    font-weight: 700;
    font-size: .6em;
    letter-spacing: -.035em;
    white-space: nowrap;
}

/* Under 360px the bar cannot hold the mark, the wordmark, the language switch
   and the login button at once, so the top bar's lockup falls back to the mark
   alone — the svg carries aria-label="Sport Match", so the link keeps its name. The
   footer lockup has the width to spare and is left whole. */
.topbar .lockup-word { display: none; }

@media (min-width: 22.5rem) {
    .topbar .lockup-word { display: inline; }
}

.lockup-word span { color: var(--chq-mark-accent); }

.tone-auto { color: var(--text-primary); --chq-mark-accent: var(--accent-text); }
.tone-dark { color: #fff; --chq-mark-accent: oklch(72% .15 258); } /* the brand's own accent-on-ink */

/* ===========================================================================
   Top bar — used light on the legal pages, and inside the ink hero on the
   home page (see .hero .topbar below).
   =========================================================================== */

.topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    padding-block: 1.5rem;
}

.site-header {
    border-bottom: 1px solid var(--border-subtle);
    background-color: var(--surface-card);
}

/* Everything that sits opposite the lockup: the language switch, then the way
   into the app. The login button is the only call to action in the bar, so it
   goes last — furthest right, where the eye lands after the copy.

   The gap sets the button apart from the language switch rather than letting
   the two read as one control group: they do unrelated jobs, and the switch is
   quiet text against a bordered call to action.

   Three items on one line is a tight fit on a 360px phone once the label is
   the Polish "Zaloguj się", so the bar runs on narrower gaps and a compact
   button and only loosens up once there is room for it. */
.topbar-actions {
    display: flex;
    align-items: center;
    /* .5rem, not more, below 30rem: with the Help link the Polish bar is four
       items, and at 360px wider gaps (here and in .topbar) pushed "Zaloguj się"
       5px off screen. */
    gap: .5rem;
}

.topbar-actions .btn { padding-inline: .75rem; }

@media (min-width: 30rem) {
    .topbar { gap: 1rem; }
    .topbar-actions { gap: 1.25rem; }
    .topbar-actions .btn { padding-inline: .9rem; }
}

/* Signed in to the app (script.js, initAppButton): the button says "Go to the
   app" — too long for the phone bar described above, so below 34rem it is the
   short "Open app" / "Aplikacja" (the Polish long label needs ~32rem beside
   the Help link and the language switch). */
.topbar-actions .app-label-long { display: none; }

@media (min-width: 34rem) {
    .topbar-actions .app-label-long { display: inline; }
    .topbar-actions .app-label-short { display: none; }
}

.lang-switch {
    display: flex;
    gap: .25rem;
}

.lang-btn {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .14em;
    text-transform: uppercase;
    padding: .5rem .7rem;
    border-radius: var(--radius-md);
    border: 1px solid transparent;
    background: none;
    cursor: pointer;
    color: var(--text-tertiary);
    transition: color var(--dur-color) var(--ease-brand),
                background-color var(--dur-color) var(--ease-brand),
                border-color var(--dur-color) var(--ease-brand);
}

.lang-btn:hover {
    color: var(--text-primary);
    background-color: var(--surface-inset);
    text-decoration: none;
}

/* On the home page the switch is a pair of buttons toggling one bilingual
   document, so the active one is aria-pressed. On the legal pages each
   language is its own URL, so the switch is a pair of links and the active
   one is aria-current. Same treatment either way. */
.lang-btn[aria-pressed="true"],
.lang-btn[aria-current="page"] {
    color: var(--accent-soft-fg);
    background-color: var(--accent-soft-bg);
}

/* ===========================================================================
   Hero — the one full-bleed ink panel on the site.

   The design system reserves --surface-inverse for exactly two things: the
   marketing/auth panel and tooltips. A landing hero *is* the marketing panel,
   so it gets the ink — and nothing else does, which is what keeps it
   emphatic.
   =========================================================================== */

.hero,
.landing-bar {
    background-color: var(--surface-hero);
    border-bottom: 1px solid oklch(100% 0 0 / .08);
    color: #fff;

    /* On-ink roles for the hero's own copy and controls. Borders are
       translucent white rather than fixed greys, so they sit correctly on the
       ink at 0.21 (light) and slate-900 (dark) alike. */
    --on-ink-2:      var(--color-slate-300);
    --on-ink-3:      var(--color-slate-400);
    --on-ink-border: oklch(100% 0 0 / .10);
}

.hero .lang-btn,
.landing-bar .lang-btn { color: var(--on-ink-3); }

.hero .lang-btn:hover,
.landing-bar .lang-btn:hover {
    color: #fff;
    background-color: oklch(100% 0 0 / .06);
}

.hero .lang-btn[aria-pressed="true"],
.hero .lang-btn[aria-current="page"],
.landing-bar .lang-btn[aria-pressed="true"] {
    color: var(--color-accent-on-dark);
    background-color: oklch(100% 0 0 / .07);
    border-color: var(--on-ink-border);
}

/* ---------------------------------------------------------------------------
   Landing bar — the landing page's top bar, kept on screen while the page
   scrolls. Same ink as the hero, so at the top of the page the two read as one
   panel; the hero then gives up its own top border (it has none) and the bar
   gains a hairline only once content scrolls under it (`is-scrolled`, set by
   script.js, which also publishes the bar's height as --landing-bar-h so the
   pricing table's header can stick just below it).
   --------------------------------------------------------------------------- */

.landing-bar {
    position: sticky;
    top: 0;
    z-index: 40;
    color: #fff;
    border-bottom: 1px solid transparent;
    transition: border-color .2s, box-shadow .2s;
}

.landing-bar .topbar { padding-block: 1rem; }

.landing-bar.is-scrolled {
    border-bottom-color: oklch(100% 0 0 / .08);
    box-shadow: 0 6px 18px -10px oklch(0% 0 0 / .45);
}

/* Anchor jumps (#pricing) land below the bar, not under it. */
html { scroll-padding-top: var(--landing-bar-h, 0px); }

.hero-grid {
    display: grid;
    gap: clamp(2.5rem, 5vw, 4rem);
    padding-block: clamp(2.5rem, 6vw, 4.5rem) clamp(3.5rem, 7vw, 5.5rem);
    align-items: center;
}

@media (min-width: 62rem) {
    /* Top-aligned, not centred: the preview's top edge lines up with the top of the
       headline and stays put when a tab with more or fewer rows is chosen — only its
       bottom edge moves with the content. */
    .hero-grid { grid-template-columns: 1.05fr .95fr; align-items: start; }
}

.hero-copy {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1.25rem;
}

.hero-copy .eyebrow { color: var(--color-accent-on-dark); }
.hero-copy h1 { font-size: var(--text-display); }

.hero-copy .lede {
    font-size: var(--text-lg);
    line-height: 1.6;
    color: var(--on-ink-2);
    max-width: 46ch;
}

.hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
    margin-top: .5rem;
}

/* ===========================================================================
   Buttons
   =========================================================================== */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    padding: .8rem 1.35rem;
    font-family: var(--font-sans);
    font-size: var(--text-base);
    font-weight: 600;
    border-radius: var(--radius-lg);
    border: 1px solid transparent;
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color var(--dur-color) var(--ease-brand),
                border-color var(--dur-color) var(--ease-brand),
                color var(--dur-color) var(--ease-brand);
}

.btn:hover { text-decoration: none; }

.btn-primary { background-color: var(--action-primary); color: #fff; }
.btn-primary:hover { background-color: var(--action-primary-hover); }
.btn-primary:active { background-color: var(--action-primary-active); }

.btn-primary:disabled {
    background-color: var(--color-slate-400);
    cursor: default;
}

/* The ghost pair: same shape, one for the ink hero and one for light surfaces
   like the legal pages' header. */
.btn-ghost {
    background: none;
    color: var(--text-primary);
    border-color: var(--border-subtle);
}

.btn-ghost:hover {
    background-color: var(--surface-inset);
    border-color: var(--border-default);
}

.btn-ghost-dark {
    background: none;
    color: #fff;
    border-color: var(--on-ink-border);
}

.btn-ghost-dark:hover {
    background-color: oklch(100% 0 0 / .06);
    border-color: oklch(100% 0 0 / .2);
}

.btn-sm { padding: .5rem .9rem; font-size: var(--text-sm); }
.btn-block { width: 100%; }

/* ===========================================================================
   The hero's product preview.

   Three real screens behind tabs — the week's sessions, who has confirmed for
   them, and what the club is owed. The calendar leads deliberately: it is the
   part of the week a coach actually plans around, and it opens on something
   the visitor can act on rather than on somebody's arrears.

   The product is themeable, so the preview carries the app's own theme
   switcher and demonstrates it. Both states are one token set, swapped by
   [data-preview-theme]; every rule below reads a token and never a theme
   value directly, which is the same discipline the page itself uses.

   Dark is the default: on the ink panel it recedes, so the headline still
   leads. Switched to bright it becomes a light panel sitting on dark — the
   "things that overlap" case the system reserves shadow-lg for — so
   elevation appears exactly then and not before.
   =========================================================================== */

.preview {
    /* --- dark (default): translucent white over the ink panel ------------- */
    --app-card:      oklch(100% 0 0 / .04);
    --app-inset:     oklch(100% 0 0 / .02);
    --app-rule:      oklch(100% 0 0 / .08);
    --app-border:    oklch(100% 0 0 / .10);
    --app-ink:       #fff;
    --app-3:         var(--color-slate-400);
    --app-avatar-bg: oklch(100% 0 0 / .10);
    --app-shadow:    none;

    --app-paid-bg: oklch(69% .14 150 / .16); --app-paid-fg: var(--color-green-400);
    --app-due-bg:  oklch(76% .14 76  / .16); --app-due-fg:  var(--color-amber-400);
    --app-over-bg: oklch(67% .17 25  / .16); --app-over-fg: var(--color-red-400);

    --app-amt-over: var(--color-red-400);
    --app-amt-due:  var(--color-amber-400);
    --app-amt-zero: var(--color-slate-400);

    /* Tabs and theme switcher, mirroring ThemeSwitcher.tsx's compact variant. */
    --app-btn-fg:       var(--color-slate-400);
    --app-btn-hover-bg: oklch(100% 0 0 / .06);
    --app-btn-on-bg:    oklch(24% .08 258 / .55);
    --app-btn-on-fg:    var(--color-indigo-300);

    background-color: var(--app-card);
    border: 1px solid var(--app-border);
    border-radius: var(--radius-xl);
    overflow: hidden;
    box-shadow: var(--app-shadow);
    /* .hero sets color:#fff — anchor it so nothing inside inherits by accident. */
    color: var(--app-ink);
}

/* --- bright: the app's own default surface ------------------------------ */
.preview[data-preview-theme="light"] {
    --app-card:      #fff;
    --app-inset:     var(--color-slate-50);
    --app-rule:      var(--color-slate-200);
    --app-border:    var(--color-slate-300);
    --app-ink:       var(--color-slate-900);
    --app-3:         var(--color-slate-500);
    --app-avatar-bg: var(--color-slate-100);
    --app-shadow:    var(--shadow-lg);

    --app-paid-bg: var(--color-green-100); --app-paid-fg: var(--color-green-700);
    --app-due-bg:  var(--color-amber-100); --app-due-fg:  var(--color-amber-700);
    --app-over-bg: var(--color-red-100);   --app-over-fg: var(--color-red-700);

    --app-amt-over: var(--color-red-600);
    --app-amt-due:  var(--color-amber-700);
    --app-amt-zero: var(--color-slate-400);

    --app-btn-fg:       var(--color-slate-500);
    --app-btn-hover-bg: var(--color-slate-50);
    --app-btn-on-bg:    var(--color-indigo-50);
    --app-btn-on-fg:    var(--color-indigo-700);
}

.preview-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .5rem 1rem;
    padding: .7rem .8rem;
    border-bottom: 1px solid var(--app-rule);
}

/* Tabs carry the same mono label treatment as a column header — they name
   three screens, which is exactly what a col-label does elsewhere. */
.preview-tabs {
    display: flex;
    align-items: center;
    gap: .15rem;
    min-width: 0;
}

.preview-tabs button {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .14em;
    text-transform: uppercase;
    white-space: nowrap;
    padding: .4rem .6rem;
    border: 0;
    border-radius: var(--radius-md);
    background: none;
    color: var(--app-btn-fg);
    cursor: pointer;
    transition: background-color var(--dur-color) var(--ease-brand),
                color var(--dur-color) var(--ease-brand);
}

.preview-tabs button:hover { background-color: var(--app-btn-hover-bg); }

.preview-tabs button[aria-selected="true"] {
    background-color: var(--app-btn-on-bg);
    color: var(--app-btn-on-fg);
}

.preview-panel[hidden] { display: none; }

.preview-note {
    padding: .95rem 1.25rem .35rem;
    font-size: var(--text-sm);
    color: var(--app-3);
}

/* Icon-only buttons in a row — geometry lifted from the compact variant:
   p-1.5, rounded-md, gap-1, 14px lucide icons. */
.preview-theme {
    display: flex;
    align-items: center;
    gap: .25rem;
    flex: none;
}

.preview-theme button {
    display: grid;
    place-items: center;
    padding: .375rem;
    background: none;
    border: 0;
    border-radius: var(--radius-md);
    color: var(--app-btn-fg);
    cursor: pointer;
    transition: background-color var(--dur-color) var(--ease-brand),
                color var(--dur-color) var(--ease-brand);
}

.preview-theme button:hover { background-color: var(--app-btn-hover-bg); }

.preview-theme button[aria-pressed="true"] {
    background-color: var(--app-btn-on-bg);
    color: var(--app-btn-on-fg);
}

.preview-theme svg { width: 14px; height: 14px; display: block; }

.preview-scroll { overflow-x: auto; }

.preview table { width: 100%; min-width: 22rem; }

.preview thead th {
    padding: .7rem 1.25rem;
    text-align: left;
    color: var(--app-3);
    border-bottom: 1px solid var(--app-rule);
    font-weight: 500;
}

.preview thead th.num,
.preview tbody td.num { text-align: right; }

.preview tbody td {
    padding: .85rem 1.25rem;
    font-size: var(--text-sm);
    border-bottom: 1px solid var(--app-rule);
}

.preview tbody tr:last-child td { border-bottom: 0; }

.preview .person {
    display: flex;
    align-items: center;
    gap: .6rem;
    color: var(--app-ink);
}

.avatar {
    width: 26px;
    height: 26px;
    border-radius: 999px;
    flex: none;
    background-color: var(--app-avatar-bg);
    border: 1px solid var(--app-rule);
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    display: grid;
    place-items: center;
    color: var(--app-3);
}

.preview-foot {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    padding: .9rem 1.25rem;
    border-top: 1px solid var(--app-rule);
    background-color: var(--app-inset);
}

.preview-foot .col-label { color: var(--app-3); }

.preview-foot .total {
    font-size: var(--text-base);
    font-weight: 500;
    color: var(--app-ink);
}

/* Red only where it means something is owed — not on a count of sessions or replies. */
.preview-foot .total-overdue { color: var(--app-amt-over); }

/* Amounts carry their state in colour as well as in sign. */
.preview .amt-overdue { color: var(--app-amt-over); }
.preview .amt-due     { color: var(--app-amt-due); }
.preview .amt-zero    { color: var(--app-amt-zero); }

/* ===========================================================================
   Status chips
   =========================================================================== */

.chip {
    display: inline-block;
    padding: .2rem .5rem;
    border-radius: var(--radius-md);
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: .1em;
    text-transform: uppercase;
    white-space: nowrap;
}

/* Inside the preview the chips follow the preview's own theme. */
.preview .chip-paid    { background-color: var(--app-paid-bg); color: var(--app-paid-fg); }
.preview .chip-due     { background-color: var(--app-due-bg);  color: var(--app-due-fg); }
.preview .chip-overdue { background-color: var(--app-over-bg); color: var(--app-over-fg); }

/* Everywhere else they follow the page theme. */
.chip-success { background-color: var(--success-bg); color: var(--success-fg); }
.chip-warning { background-color: var(--warning-bg); color: var(--warning-fg); }
.chip-danger  { background-color: var(--danger-bg);  color: var(--danger-fg); }
.chip-accent  { background-color: var(--accent-soft-bg); color: var(--accent-soft-fg); }

/* ===========================================================================
   Feature cards — flat, hairline, no shadow.
   =========================================================================== */

.card-grid {
    display: grid;
    gap: 1.25rem;
}

@media (min-width: 40rem) {
    .card-grid { grid-template-columns: repeat(2, 1fr); }
}

.card {
    background-color: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-xl);
    padding: 1.5rem;
    display: flex;
    flex-direction: column;
    gap: .6rem;
    transition: border-color var(--dur-ui) var(--ease-brand);
}

.card:hover { border-color: var(--border-default); }
.card .eyebrow { color: var(--accent-text); }
.card h3 { font-size: var(--text-xl); }

.card p {
    color: var(--text-secondary);
    font-size: var(--text-sm);
    line-height: 1.65;
}

.card-fields {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    margin-top: auto;
    padding-top: 1rem;
    border-top: 1px solid var(--border-subtle);
}

.field {
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--text-tertiary);
    background-color: var(--surface-inset);
    border-radius: var(--radius-md);
    padding: .25rem .5rem;
}

/* ===========================================================================
   Pricing — a comparison table, not three cards.

   The system's rule is that anything read *down a column* is mono and
   tabular. Three prices beside three member limits is the definition of that,
   so pricing gets the same treatment the app gives money everywhere else.
   =========================================================================== */

.price-wrap {
    background-color: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-xl);
    /* clip, not hidden: `hidden` makes this a scroll container, and the plan
       table's sticky header and buttons would then stick to it instead of to
       the screen. */
    overflow: clip;
}

/* position: relative makes this the containing block of the table's .sr-only
   spans (position: absolute). Without it they anchor outside the scroller, are
   not clipped by it, and stretch the whole page sideways on a phone. */
.price-scroll { overflow-x: auto; position: relative; }

.price-table {
    width: 100%;
    min-width: 34rem;
}

.price-table thead th {
    padding: .9rem 1.25rem;
    text-align: left;
    font-weight: 500;
    color: var(--text-tertiary);
    background-color: var(--surface-inset);
    border-bottom: 1px solid var(--border-subtle);
}

.price-table th.num, .price-table td.num,
.price-table th.act, .price-table td.act { text-align: right; }

.price-table tbody td {
    padding: 1.1rem 1.25rem;
    border-bottom: 1px solid var(--border-subtle);
    vertical-align: middle;
}

.price-table tbody tr:last-child td { border-bottom: 0; }

.price-table .plan {
    display: flex;
    align-items: center;
    gap: .6rem;
    font-size: var(--text-lg);
    font-weight: 600;
    letter-spacing: -.02em;
}

.price-table .limit {
    color: var(--text-secondary);
    font-size: var(--text-sm);
}

.price-table .amount {
    font-size: var(--text-xl);
    font-weight: 500;
}

/* The recommended row is marked by an accent stripe on the row itself — the
   one place the accent is used as a surface outside a button. */
.price-table tr.featured { background-color: var(--accent-soft-bg); }
.price-table tr.featured td:first-child { box-shadow: inset 3px 0 0 var(--action-primary); }
.price-table tr.featured .amount { color: var(--accent-soft-fg); }

/* ---------------------------------------------------------------------------
   Plan comparison
   The table IS the comparison: one column per plan, one row per capability, so
   the difference between the two plans is read down a column rather than
   reconstructed from two separate feature lists. The AI Boost column carries
   the accent as a surface for its whole height — the same "accent as a
   surface only here" exception the old featured row had, moved from a row to
   a column because that is the axis that now means something.
   --------------------------------------------------------------------------- */

.plan-table {
    width: 100%;
    /* Four columns now — the feature label plus three plans. Below this the wrapper
       scrolls horizontally rather than letting the columns crush together (only
       without JavaScript: with it, narrower screens get the plan picker). */
    min-width: 56rem;
    border-collapse: collapse;
}

.plan-table thead th {
    padding: 1.25rem;
    text-align: left;
    vertical-align: bottom;
    background-color: var(--surface-inset);
    border-bottom: 1px solid var(--border-subtle);
    font-weight: 500;
}

/* Each plan header stacks name / price / unit / who it covers. */
.plan-table .plan-col { text-align: center; }

.plan-table .plan-name {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: .5rem;
    font-size: var(--text-lg);
    font-weight: 600;
    letter-spacing: -.02em;
    color: var(--text-primary);
}

.plan-table .plan-col .amount {
    display: block;
    margin-top: .5rem;
    font-size: var(--text-2xl);
    font-weight: 500;
    line-height: 1.1;
}

.plan-table :where(.per) {
    display: block;
    font-size: var(--text-xs);
    color: var(--text-tertiary);
}

/* The gross (VAT-inclusive) amount under each net price: one quiet line,
   never wrapped, so "159,90 zł brutto" does not split into two numbers. */
.plan-table :where(.plan-gross) { white-space: nowrap; }

.plan-table :where(.plan-for) {
    display: block;
    margin-top: .35rem;
    font-size: var(--text-xs);
    color: var(--text-secondary);
}

.plan-table tbody th,
.plan-table tfoot th {
    padding: .95rem 1.25rem;
    text-align: left;
    font-weight: 500;
    color: var(--text-primary);
    border-bottom: 1px solid var(--border-subtle);
    max-width: 30rem;
}

.plan-table tbody td,
.plan-table tfoot td {
    padding: .95rem 1.25rem;
    text-align: center;
    border-bottom: 1px solid var(--border-subtle);
    vertical-align: middle;
}

/* A row carries a short line of explanation only when its label alone does
   not say what changes for the club: "AI assistant" does not tell a coach what
   changes on a Sunday evening, SMS is a member-paid add-on, an "electronic
   signature check" needs to say what is checked. Self-evident rows get no note.
   The phone's plan picker (below) shows the same notes under each feature. */
.plan-table :where(.row-note) {
    display: block;
    margin-top: .3rem;
    font-size: var(--text-sm);
    font-weight: 400;
    color: var(--text-secondary);
    line-height: 1.6;
    max-width: 46ch;
}

.plan-table .row-new th { padding-top: 1.15rem; padding-bottom: 1.15rem; }

/* One <tbody> per area (club, training, money, documents, …) with a label row
   on top, so a table of two dozen rows can be scanned for the part a reader
   cares about. The plan columns stay empty here but keep the accent surface,
   so the AI Boost column reads as one unbroken stripe. */
.plan-table .row-group th {
    padding-top: 1.6rem;
    padding-bottom: .45rem;
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}
.plan-table .row-group td { padding-top: 1.6rem; padding-bottom: .45rem; }

/* Keeps "+30 zł" and the two CTA buttons on one line — these cells are narrow by
   design and a wrapped price reads as two numbers. */
.plan-table .mark { white-space: nowrap; }

.plan-table .tick {
    color: var(--success-fg);
    font-size: var(--text-lg);
    line-height: 1;
}

.plan-table .dash {
    color: var(--text-tertiary);
    font-size: var(--text-lg);
    line-height: 1;
}

/* The accent column. `featured` is on every cell rather than a column element
   because a <col> cannot paint over the cells' own borders. */
.plan-table .featured { background-color: var(--accent-soft-bg); }
.plan-table thead th.featured .plan-name,
.plan-table thead th.featured .amount { color: var(--accent-soft-fg); }

.plan-table tfoot th,
.plan-table tfoot td {
    border-bottom: 0;
    border-top: 1px solid var(--border-default);
}

.plan-table tfoot .amount {
    font-size: var(--text-base);
    font-weight: 500;
}

.plan-table tfoot .cta-row th,
.plan-table tfoot .cta-row td { border-top: 0; padding-top: 0; }

/* ---------------------------------------------------------------------------
   Sticky plan header and "Set up your club" buttons.

   The plan names stay at the top while the feature rows scroll past, and the
   buttons wait at the bottom of the screen until the table's own last row
   scrolls into view — then they simply travel up with it (plain
   `position: sticky; bottom: 0`, which is exactly that behaviour).

   The header that stays at the top is not the table's own <thead> but a
   compact copy of it — plan names and prices only, without "net / mo.", the
   gross amount, "for 50 members" and the Recommended chip — that script.js
   builds and shows (`is-on`) once the real header has scrolled away. A
   separate layer, so it can be much shorter than the header without moving a
   single row; its columns take the header's measured widths (--plan-pin-cols).
   It is a zero-height sticky block before the table, so it sticks where the
   header would have, and leaves with the buttons (--plan-head-shift, script.js)
   once they have passed the middle of the screen.

   Sticky sticks to the nearest scroll container. Where the table fits the
   page (wide screens) nothing scrolls sideways, so the scroller lets go and
   both stick to the screen, the header just under the landing bar. Narrower,
   the table must scroll sideways, so the scroller becomes a box at most one
   screen tall that scrolls both ways, and header and buttons stick inside it.
   Below 64rem the table gives way to the plan picker (below), so the box is
   what a phone without JavaScript gets.
   --------------------------------------------------------------------------- */

.plan-pin {
    position: sticky;
    top: 0;
    z-index: 3;
    height: 0;   /* takes no room; its row hangs below it. Width: the table's (script.js). */
}

.plan-pin-row {
    display: grid;
    grid-template-columns: var(--plan-pin-cols, 1.6fr 1fr 1fr 1fr);
    background-color: var(--surface-inset);
    box-shadow: 0 1px 0 var(--border-subtle), 0 8px 14px -12px oklch(0% 0 0 / .35);
    transform: translateY(var(--plan-head-shift, 0px));
    /* Arrives by settling down from under the bar; never transitions `transform`,
       which follows the scroll frame by frame. */
    opacity: 0;
    visibility: hidden;
    translate: 0 -.5rem;
    transition: opacity var(--dur-ui) var(--ease-brand),
                translate var(--dur-ui) var(--ease-brand),
                visibility 0s linear var(--dur-ui);
}

.plan-pin.is-on .plan-pin-row {
    opacity: 1;
    visibility: visible;
    translate: 0 0;
    transition-delay: 0s;
}

/* One line per plan, so the bar is the same height in every column and language. */
.plan-pin-cell {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: .5rem;
    padding: .7rem .5rem;
    white-space: nowrap;
}

.plan-pin-cell.featured { background-color: var(--accent-soft-bg); }

.plan-pin-name {
    font-weight: 600;
    letter-spacing: -.02em;
    color: var(--text-primary);
}

.plan-pin-cell .amount {
    font-size: var(--text-base);
    font-weight: 500;
    color: var(--text-secondary);
}

.plan-pin-cell.featured .plan-pin-name,
.plan-pin-cell.featured .amount { color: var(--accent-soft-fg); }

.plan-table tfoot .cta-row th,
.plan-table tfoot .cta-row td {
    position: sticky;
    bottom: 0;
    z-index: 2;
    padding-top: .75rem;
    padding-bottom: .9rem;
    background-color: var(--surface-card);
    transition: box-shadow .2s;
}

.plan-table tfoot .cta-row td.featured { background-color: var(--accent-soft-bg); }

/* Only while they float over the rows (script.js sets `is-stuck`). */
.plan-table tfoot .cta-row.is-stuck th,
.plan-table tfoot .cta-row.is-stuck td { box-shadow: 0 -1px 0 var(--border-subtle), 0 -8px 14px -12px oklch(0% 0 0 / .35); }

@media (max-width: 63.99rem) {
    .price-scroll {
        overflow: auto;
        max-height: calc(100svh - var(--landing-bar-h, 0px) - 1.5rem);
        overscroll-behavior-x: contain;
    }
}

@media (min-width: 64rem) {
    .price-scroll { overflow: visible; }
    .plan-pin { top: var(--landing-bar-h, 0px); }

    /* The chat bubble (fixed, 56px at 20px from the right and bottom edges) would
       cover the pinned Pro button wherever the table reaches within ~60px of the
       screen's right edge — up to ~1100px wide. There the card steps in from both
       sides instead, just enough (at most 2.5rem, which still leaves the table its
       56rem) for the button to end left of the bubble. */
    .price-wrap { margin-inline: clamp(0px, 35rem - 50vw, 2.5rem); }
}

/* ---------------------------------------------------------------------------
   Plan picker — the comparison on a phone or an upright tablet.

   Four columns do not fit a phone or a tablet held upright — the plan columns
   would start off screen — so below 64rem the table gives way to one
   plan at a time: a segmented switcher (a tablist: Standard / AI Boost / Pro,
   each with its price, AI Boost selected first) that stays under the landing
   bar, then the chosen plan's price block and its feature list, ✓ or —, with
   the plans that do have a missing feature named under it. Switching plans
   keeps the scroll position, so the same row can be compared plan to plan.

   Everything in it is cloned from the table by script.js; until it has run
   (or without JavaScript) the table stays, and the picker does not exist.

   "Set up your club" waits at the bottom of the screen until the list ends.
   The chat bubble (bottom right, 56px at 20px from the edges, owned by the
   messenger widget) stays where it is; the button is centred and kept clear of
   the bubble's column on both sides, so the two never overlap.
   --------------------------------------------------------------------------- */

.plan-picker { display: none; }

@media (max-width: 63.99rem) {
    .has-plan-picker .price-wrap { display: none; }
    .has-plan-picker .plan-picker { display: block; }
}

.plan-switch-bar {
    position: sticky;
    top: var(--landing-bar-h, 0px);
    z-index: 5;
    padding-block: .5rem;
    margin-top: -.5rem;
    background-color: var(--surface-inset);
    transition: box-shadow .2s;
}

.plan-switch-bar.is-stuck { box-shadow: 0 10px 12px -12px oklch(0% 0 0 / .35); }

.plan-switch {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: .25rem;
    padding: .25rem;
    background-color: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-xl);
}

.plan-switch-tab {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .1rem;
    min-height: 2.75rem;
    padding: .45rem .25rem;
    border: 0;
    border-radius: var(--radius-lg);
    background: none;
    color: var(--text-primary);
    font: inherit;
    cursor: pointer;
    transition: background-color var(--dur-color) var(--ease-brand),
                color var(--dur-color) var(--ease-brand);
}

.plan-switch-tab:hover { background-color: var(--surface-inset); }

.plan-switch-name {
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: -.01em;
    white-space: nowrap;
}

.plan-switch-price {
    font-size: var(--text-xs);
    color: var(--text-secondary);
}

.plan-switch-tab[aria-selected="true"] {
    background-color: var(--action-primary);
    color: #fff;
}

.plan-switch-tab[aria-selected="true"] .plan-switch-price { color: oklch(100% 0 0 / .85); }

.plan-panel {
    margin-top: .5rem;
    background-color: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-xl);
    /* clip, not hidden — the button inside must still stick to the screen. */
    overflow: clip;
    animation: rise var(--dur-panel) var(--ease-brand) both;
}

.plan-panel[hidden] { display: none; }

.plan-summary {
    padding: 1.25rem 1.25rem 1.1rem;
    background-color: var(--surface-inset);
    border-bottom: 1px solid var(--border-subtle);
}

.plan-panel.featured .plan-summary { background-color: var(--accent-soft-bg); }

.plan-summary .plan-name {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .5rem;
    font-size: var(--text-lg);
    font-weight: 600;
    letter-spacing: -.02em;
}

.plan-price {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: .5rem;
    margin-top: .35rem;
}

.plan-price .amount {
    font-size: var(--text-3xl);
    font-weight: 500;
    line-height: 1.1;
}

.plan-panel.featured .plan-name,
.plan-panel.featured .plan-price .amount { color: var(--accent-soft-fg); }

.plan-price .per,
.plan-meta,
.plan-extra {
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

.plan-meta { margin-top: .2rem; }

/* "159,90 zł brutto · za 50 członków" — the dot only between the two. */
.plan-meta .plan-for::before { content: " · "; }

.plan-extra {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    column-gap: .5rem;
    margin-top: .6rem;
    padding-top: .6rem;
    border-top: 1px solid var(--border-subtle);
}

.plan-extra .amount {
    font-weight: 500;
    color: var(--text-primary);
}

.plan-group {
    padding: 1.4rem 1.25rem .35rem;
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}

.plan-features {
    margin: 0;
    padding: 0;
    list-style: none;
}

.plan-features li {
    position: relative;   /* contains the .sr-only status (see .price-scroll) */
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    padding: .8rem 1.25rem;
    border-bottom: 1px solid var(--border-subtle);
}

.plan-features li:last-child { border-bottom: 0; }

.plan-mark {
    flex: none;
    width: 1.1rem;
    text-align: center;
    font-size: var(--text-lg);
    line-height: 1.35rem;
}

.plan-mark.tick { color: var(--success-fg); }
.plan-mark.dash { color: var(--text-tertiary); }

.plan-feature {
    min-width: 0;
    font-weight: 500;
    line-height: 1.45;
}

.plan-features .is-off .plan-feature { color: var(--text-tertiary); }

.plan-feature .row-note {
    display: block;
    margin-top: .25rem;
    font-size: var(--text-sm);
    font-weight: 400;
    line-height: 1.55;
    color: var(--text-secondary);
    max-width: 60ch;
}

.plan-features .is-off .row-note { color: var(--text-tertiary); }

.plan-upsell {
    display: block;
    margin-top: .3rem;
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--accent-text);
}

.plan-cta {
    position: sticky;
    bottom: 0;
    z-index: 2;
    display: flex;
    justify-content: center;
    /* Clear of the chat bubble: it spans 20–76px from the screen's right edge,
       the card's edge sits 25px in, so 60px each side keeps the centred button
       out of its column. The bottom padding lines the button up with it. */
    padding: .9rem 3.75rem calc(1.25rem + env(safe-area-inset-bottom, 0px));
    background-color: var(--surface-card);
    border-top: 1px solid var(--border-subtle);
    transition: box-shadow .2s;
}

.plan-cta.is-stuck { box-shadow: 0 -8px 14px -12px oklch(0% 0 0 / .35); }

.plan-cta .btn {
    width: 100%;
    max-width: 16rem;
    min-height: 2.75rem;
}

/* Screen-reader-only, so a ✓ is announced as what it means. The site's own
   language switch hides the inactive copy with display:none, which layers over
   this correctly: the wrong language is gone, the right one is unseen but read. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.price-notes {
    display: flex;
    flex-direction: column;
    gap: .6rem;
    margin-top: 1.5rem;
}

.price-notes .note {
    font-size: var(--text-sm);
    font-weight: 500;
}

.price-notes .fine {
    font-size: var(--text-xs);
    color: var(--text-tertiary);
    line-height: 1.7;
    max-width: 70ch;
}

/* ===========================================================================
   Footer — light, hairline rule. Identifiers (NIP, REGON, phone) are set in
   mono, because the system's split is by what the reader does with the text:
   language in Space Grotesk, anything compared or copied in Plex Mono.
   =========================================================================== */

footer {
    border-top: 1px solid var(--border-subtle);
    padding-block: 3rem 2.5rem;
    background-color: var(--surface-card);
}

.footer-grid {
    display: flex;
    flex-direction: column;
    gap: 2rem;
}

@media (min-width: 48rem) {
    .footer-grid {
        flex-direction: row;
        justify-content: space-between;
        gap: 3rem;
    }
}

.footer-brand {
    display: flex;
    flex-direction: column;
    gap: .85rem;
    align-items: flex-start;
}

.footer-brand .lockup { font-size: 24px; }

.footer-tagline {
    font-size: var(--text-sm);
    color: var(--text-tertiary);
    max-width: 26ch;
}

.footer-nav,
.footer-contact {
    display: flex;
    flex-direction: column;
    gap: .6rem;
}

.footer-nav .col-label,
.footer-contact .col-label {
    color: var(--text-tertiary);
    margin-bottom: .2rem;
}

.footer-nav a {
    color: var(--text-secondary);
    font-size: var(--text-sm);
    font-weight: 500;
}

.footer-nav a:hover { color: var(--accent-text); }

.footer-contact a { font-size: var(--text-sm); }

.footer-legal {
    margin-top: 2.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--border-subtle);
    display: flex;
    flex-direction: column;
    gap: .5rem;
}

.footer-legal p {
    font-size: var(--text-xs);
    color: var(--text-tertiary);
    line-height: 1.7;
}

.footer-legal .data-num { font-size: 11px; }

/* ===========================================================================
   Legal pages
   =========================================================================== */

.legal {
    padding-block: 3rem 5rem;
}

.legal .container { max-width: var(--container-prose); }

.legal-back {
    display: inline-block;
    margin-bottom: 2rem;
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}

.legal-back:hover { color: var(--accent-text); }

.legal h1 {
    font-size: var(--text-section);
    margin-bottom: .5rem;
}

.legal .legal-updated {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    color: var(--text-tertiary);
    margin-bottom: 2.5rem;
}

.legal h2 {
    font-size: var(--text-xl);
    margin: 2.5rem 0 .75rem;
}

.legal h3 {
    font-size: var(--text-lg);
    margin: 1.75rem 0 .5rem;
}

.legal p,
.legal li {
    color: var(--text-secondary);
    line-height: 1.7;
}

.legal p { margin-bottom: 1rem; }

.legal ol,
.legal ul {
    margin: 0 0 1rem 1.25rem;
    padding-left: .5rem;
}

.legal li { margin-bottom: .5rem; }

.legal strong { color: var(--text-primary); }

.legal table {
    width: 100%;
    margin-bottom: 1rem;
    font-size: var(--text-sm);
}

.legal th,
.legal td {
    padding: .6rem .75rem;
    text-align: left;
    border-bottom: 1px solid var(--border-subtle);
    color: var(--text-secondary);
}

.legal th { color: var(--text-primary); font-weight: 600; }

/* ===========================================================================
   Help pages — /pomoc/ and /help/, generated by tools/help/build.py.

   The install article shows one browser's guide at a time (help-assets/help.js).
   Screenshots carry a ring over the control each step asks to tap; its box comes
   from the automation that took the screenshot, as percentages, so it scales
   with the image.
   =========================================================================== */

.help {
    padding-block: 3rem 5rem;
}

.help .container { max-width: var(--container-prose); }

.help h1 {
    font-size: var(--text-section);
    margin-bottom: .75rem;
}

.help-lead {
    color: var(--text-secondary);
    font-size: var(--text-lg);
    line-height: 1.6;
    margin-bottom: 2rem;
}

.help-crumbs,
.help-label,
.help-back {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}

.help-crumbs { margin-bottom: 1.25rem; }
.help-crumbs a,
.help-back { color: var(--text-tertiary); }
.help-crumbs a:hover,
.help-back:hover { color: var(--accent-text); }

/* Browser + orientation pickers -------------------------------------------- */

.help-controls {
    padding: 1.25rem;
    margin-bottom: 2.5rem;
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-xl);
}

.help-label { margin-bottom: .6rem; }

.help-chips {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.help-chip,
.help-segmented button {
    font: inherit;
    font-size: var(--text-sm);
    padding: .45rem .8rem;
    border: 1px solid var(--border-default);
    border-radius: 999px;
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    transition: background-color var(--dur-color), color var(--dur-color), border-color var(--dur-color);
}

.help-chip:hover,
.help-segmented button:hover { border-color: var(--accent-text); color: var(--text-primary); }

.help-chip[aria-pressed="true"],
.help-segmented button[aria-pressed="true"] {
    background: var(--action-primary);
    border-color: var(--action-primary);
    color: #fff;
}

.help-hint {
    margin-top: .6rem;
    font-size: var(--text-xs);
    color: var(--text-tertiary);
}

.help-orientation { margin-top: 1.25rem; }
.help-orientation[hidden] { display: none; }

.help-segmented {
    display: inline-flex;
    gap: .35rem;
}

/* Guides ------------------------------------------------------------------ */

.help-guide { margin-bottom: 3rem; }
.help-guide[hidden] { display: none; }

.help-guide h2 {
    font-size: var(--text-xl);
    margin-bottom: 1.25rem;
}

/* With the picker on screen, the chosen chip already names the guide. */
.help-js .help-guide h2 {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
}

.help-steps {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 1.75rem;
}

/* Portrait unless the page (or the reader) says landscape; without JS only portrait. */
.help-steps[data-orientation="landscape"],
.help-landscape .help-steps[data-orientation="portrait"] { display: none; }
.help-landscape .help-steps[data-orientation="landscape"] { display: grid; }

/* Without this a grid item is at least as wide as its content, so a landscape
   phone (35rem) would push the page sideways on a narrow screen. */
.help-step { min-width: 0; }

.help-step-head {
    display: flex;
    align-items: center;
    gap: .85rem;
}

.help-step-head p {
    flex: 1;
    min-width: 0;
    color: var(--text-secondary);
    line-height: 1.55;
}

.help-step-head b { color: var(--text-primary); font-weight: 600; }

.help-step-num {
    flex-shrink: 0;
    display: grid;
    place-items: center;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 999px;
    background: var(--accent-soft-bg);
    color: var(--accent-soft-fg);
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    font-weight: 500;
}

.help-step-icon {
    flex-shrink: 0;
    display: grid;
    place-items: center;
    width: 2.5rem;
    height: 2.5rem;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    color: var(--accent-text);
}

.help-step-icon .icon { width: 1.25rem; height: 1.25rem; }

.help-shot {
    margin: 1rem 0 0 2.6rem;
}

/* The screenshot inside a drawn phone. Every size is in cqi — a fraction of the
   phone's own width — so the bezel, the screen corners and the camera keep their
   proportions at any size. Proportions are the iPhone 17 (screen corner ≈ 13.7% of
   its short side) and the Pixel 10 Pro, both drawn without a camera — a drawn camera
   over the screenshot looked fake, so every phone is the frame only. Landscape is the phone turned with its top to the
   left, as the captures were: the island moves to the left edge and the side buttons
   to the top and bottom. */

.help-device {
    container-type: inline-size;
    width: 17.5rem;
    max-width: 100%;
    padding: 1px 2px;          /* room for the side buttons */
}

.help-device--landscape { width: 35rem; }

.help-device-body {
    --bezel: 4.3cqi;
    --radius: 12.8cqi;
    --rim: #4a4a4e;
    --button: #3a3a3e;
    position: relative;
    padding: var(--bezel);
    border-radius: calc(var(--radius) + var(--bezel));
    background: #0b0b0c;
    box-shadow:
        0 0 0 max(1.5px, .55cqi) var(--rim),
        var(--shadow-lg);
}

.help-device--iphone.help-device--landscape .help-device-body { --bezel: 2cqi; --radius: 6cqi; }
.help-device--pixel .help-device-body { --bezel: 3.4cqi; --radius: 9cqi; --rim: #2e2e31; }
.help-device--pixel.help-device--landscape .help-device-body { --bezel: 1.55cqi; --radius: 4cqi; }

.help-device-screen {
    position: relative;
    overflow: hidden;
    border-radius: var(--radius);
    line-height: 0;
    background: #000;
}

.help-device-screen img { display: block; width: 100%; height: auto; }

/* Side buttons: ::before is the power button, ::after the volume rocker. */
.help-device-body::before,
.help-device-body::after {
    content: "";
    position: absolute;
    background: var(--button);
    border-radius: 1cqi;
}

.help-device--portrait .help-device-body::before { right: -1.3cqi; top: 27%; width: 1cqi; height: 12%; }
.help-device--portrait .help-device-body::after  { left: -1.3cqi;  top: 24%; width: 1cqi; height: 10%; }
.help-device--pixel.help-device--portrait .help-device-body::before { top: 20%; height: 7%; }
.help-device--pixel.help-device--portrait .help-device-body::after  { left: auto; right: -1.3cqi; top: 31%; height: 14%; }

.help-device--landscape .help-device-body::before { top: -.6cqi; left: 27%; height: .45cqi; width: 12%; }
.help-device--landscape .help-device-body::after  { bottom: -.6cqi; left: 24%; height: .45cqi; width: 10%; }
.help-device--pixel.help-device--landscape .help-device-body::before { left: 20%; width: 7%; }
.help-device--pixel.help-device--landscape .help-device-body::after  { bottom: auto; top: -.6cqi; left: 31%; width: 14%; }

/* The home-screen result is a crop, not a whole screen, so it gets plain corners. */
.help-shot-crop {
    display: inline-block;
    max-width: 100%;
    overflow: hidden;
    border-radius: 1.25rem;
    border: 1px solid var(--border-subtle);
    box-shadow: var(--shadow-lg);
    line-height: 0;
}

.help-shot-crop img { display: block; width: 15rem; max-width: 100%; height: auto; }

.help-ring {
    position: absolute;
    border: 3px solid oklch(65% .22 25);
    border-radius: .6rem;
    box-shadow: 0 0 0 4px oklch(65% .22 25 / .25);
    animation: help-ring 1.8s var(--ease-brand) infinite;
    pointer-events: none;
}

@keyframes help-ring {
    0%, 100% { box-shadow: 0 0 0 3px oklch(65% .22 25 / .3); }
    50%      { box-shadow: 0 0 0 9px oklch(65% .22 25 / 0); }
}

@media (max-width: 40rem) {
    .help-shot { margin-left: 0; }
    .help-device--portrait { width: 15rem; }
}

/* FAQ, footer actions, index -------------------------------------------------- */

.help-faqs h2 {
    font-size: var(--text-xl);
    margin-bottom: 1rem;
}

.help-faq {
    border-bottom: 1px solid var(--border-subtle);
    padding-block: .9rem;
}

.help-faq summary {
    cursor: pointer;
    font-weight: 600;
    color: var(--text-primary);
}

.help-faq p {
    margin-top: .6rem;
    color: var(--text-secondary);
    line-height: 1.65;
}

.help-actions {
    margin-top: 2.5rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1.5rem;
}

.help-index {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: .75rem;
}

.help-index a {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    padding: 1.1rem 1.25rem;
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-xl);
    color: var(--text-secondary);
    transition: border-color var(--dur-color);
}

.help-index a:hover { border-color: var(--accent-text); text-decoration: none; }
.help-index strong { display: block; color: var(--text-primary); margin-bottom: .25rem; }
.help-index-icon { color: var(--accent-text); flex-shrink: 0; }
.help-index-icon .icon { width: 1.5rem; height: 1.5rem; }

/* Text articles (the electronic signature guide): sections of prose, step lists
   without screenshots, callouts and the document badges the app shows. ---------- */

.help-toc {
    margin-bottom: 2.5rem;
    padding: 1.25rem;
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-xl);
}

.help-toc ol {
    margin: 0;
    padding-left: 1.25rem;
    display: grid;
    gap: .35rem;
    color: var(--text-tertiary);
}

.help-section {
    margin-bottom: 3rem;
    scroll-margin-top: 1.5rem;
}

/* On pages with screenshots the sticky "Screenshots" view switcher sits on top of the
   viewport, so a #section link has to land below it, not under it. */
body:has(.help-viewpick:not([hidden])) .help-section { scroll-margin-top: 5.5rem; }

.help-section h2 {
    font-size: var(--text-xl);
    margin-bottom: 1rem;
}

.help-section h3 {
    font-size: var(--text-lg);
    margin: 1.75rem 0 1rem;
}

.help-section > p,
.help-list li {
    color: var(--text-secondary);
    line-height: 1.65;
}

.help-section > p { margin-bottom: 1rem; }
.help-section b { color: var(--text-primary); font-weight: 600; }
.help-section .help-steps { margin-bottom: 1.5rem; }

.help-list {
    margin: 0 0 1rem;
    padding-left: 1.25rem;
    display: grid;
    gap: .5rem;
}

.help-note {
    padding: 1rem 1.25rem;
    border-left: 3px solid var(--accent-text);
    border-radius: var(--radius-lg);
    background: var(--accent-soft-bg);
}

.help-section > .help-note { color: var(--text-primary); }

.help-section > .help-small {
    font-size: var(--text-sm);
    color: var(--text-tertiary);
}

.help-badges {
    list-style: none;
    margin: 0 0 1.25rem;
    padding: 0;
    display: grid;
    gap: .75rem;
}

.help-badge {
    display: flex;
    gap: .85rem;
    align-items: flex-start;
    padding: 1rem 1.25rem;
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-xl);
}

.help-badge strong { display: block; color: var(--text-primary); margin-bottom: .35rem; }
.help-badge p { color: var(--text-secondary); line-height: 1.6; }

.help-badge-icon {
    flex-shrink: 0;
    display: grid;
    place-items: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: var(--radius-lg);
    background: var(--surface-inset);
    color: var(--text-secondary);
}

.help-badge-icon .icon { width: 1.25rem; height: 1.25rem; }
.help-badge--success .help-badge-icon { background: var(--success-bg); color: var(--success-fg); }
.help-badge--warning .help-badge-icon { background: var(--warning-bg); color: var(--warning-fg); }
.help-badge--danger  .help-badge-icon { background: var(--danger-bg);  color: var(--danger-fg); }

/* Help center: hub, sections, topics and app screenshots ----------------------
   Generated pages (tools/help/build.py). Every app screenshot exists three times —
   a laptop browser window, a phone upright and the same phone turned — and a page
   shows one of them: the reader's own device by default (the media queries below,
   which also work without JavaScript), or the one picked in the "Screenshots"
   switch (help.js sets body.help-view-*). Hidden images are lazy and never load. */

.skip-link {
    position: absolute;
    left: 1rem;
    top: -3rem;
    z-index: 10;
    padding: .5rem .9rem;
    border-radius: var(--radius-lg);
    background: var(--action-primary);
    color: #fff;
}
.skip-link:focus { top: 1rem; }

.topbar-help {
    display: none;
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--text-secondary);
}
.topbar-help:hover,
.topbar-help[aria-current="page"] { color: var(--accent-text); }
.hero .topbar-help,
.landing-bar .topbar-help { color: var(--on-ink-3, oklch(80% .02 258)); }
.hero .topbar-help:hover,
.landing-bar .topbar-help:hover { color: #fff; }
@media (min-width: 30rem) { .topbar-help { display: inline; } }

.help-crumbs { display: flex; flex-wrap: wrap; gap: .5rem; }

.help-audience {
    display: flex;
    gap: .5rem;
    align-items: center;
    margin: -1rem 0 2rem;
    color: var(--text-tertiary);
    font-size: var(--text-sm);
}
.help-audience .icon { width: 1rem; height: 1rem; flex-shrink: 0; }

/* Search ------------------------------------------------------------------- */

.help-search { margin-bottom: 2rem; }
.help-search[hidden] { display: none; }
.help-search input {
    width: 100%;
    font: inherit;
    padding: .7rem 1rem;
    border: 1px solid var(--border-default);
    border-radius: var(--radius-xl);
    background: var(--surface-card);
    color: var(--text-primary);
}
.help-search input:focus { outline: 3px solid oklch(52% .19 258 / .32); border-color: var(--accent-text); }
.help-search-empty { margin-top: .75rem; color: var(--text-tertiary); }
.help-index li[hidden],
.help-hub-section[hidden] { display: none; }

/* Hub ---------------------------------------------------------------------- */

.help-hub .container { max-width: var(--container); }
.help-hub-section { margin-bottom: 3rem; }
.help-hub-head {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    margin-bottom: 1.25rem;
}
.help-hub-head h2 { font-size: var(--text-2xl); margin-bottom: .35rem; }
.help-hub-head h2 a { color: var(--text-primary); }
.help-hub-head h2 a:hover { color: var(--accent-text); }
.help-hub-head p { color: var(--text-secondary); line-height: 1.6; max-width: 62ch; }
.help-hub-icon {
    flex-shrink: 0;
    display: grid;
    place-items: center;
    width: 3rem;
    height: 3rem;
    border-radius: var(--radius-xl);
    background: var(--accent-soft-bg);
    color: var(--accent-soft-fg);
}
.help-hub-icon .icon { width: 1.5rem; height: 1.5rem; }

.help-index--compact a { padding: .8rem 1rem; align-items: center; }
.help-index--compact strong { margin-bottom: 0; font-weight: 600; }
.help-index--compact .help-index-icon .icon { width: 1.25rem; height: 1.25rem; }
@media (min-width: 40rem) {
    .help-index--grid { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 60rem) {
    .help-index--grid { grid-template-columns: 1fr 1fr 1fr; }
}

.help-contact {
    margin-top: 1rem;
    padding: 1.5rem;
    border-radius: var(--radius-xl);
    background: var(--surface-inset);
}
.help-contact h2 { font-size: var(--text-xl); margin-bottom: .5rem; }
.help-contact p { color: var(--text-secondary); line-height: 1.65; }
.help-contact b { color: var(--text-primary); }
.help-contact-actions {
    margin-top: 1rem;
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
}
.help-contact-actions .btn { display: inline-flex; align-items: center; gap: .5rem; }
.help-contact-actions .icon { width: 1.15rem; height: 1.15rem; }
.help-article .help-contact,
.help .help-contact { margin-top: 2.5rem; }

.help-others { margin-top: 3rem; }
.help-others ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .75rem 1.5rem; }
.help-others a { display: inline-flex; gap: .45rem; align-items: center; }
.help-others .icon { width: 1.1rem; height: 1.1rem; }

.help-related { margin-top: 3rem; }
.help-related h2 { font-size: var(--text-xl); margin-bottom: 1rem; }

/* Screenshot views ---------------------------------------------------------- */

.help-viewpick {
    position: sticky;
    top: 0;
    z-index: 5;
    margin: 0 0 2rem;
    padding: .75rem 1rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem 1rem;
    background: color-mix(in oklch, var(--surface-page) 88%, transparent);
    backdrop-filter: blur(8px);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-xl);
}
.help-viewpick[hidden] { display: none; }
.help-viewpick .help-label { margin: 0; }
.help-viewpick .help-segmented { flex-wrap: wrap; }

.help-app-shot { margin: 1rem 0 0 2.6rem; }
.help-section > .help-app-shot { margin: 0 0 1.5rem; }
.help-app-shot figcaption {
    margin-top: .6rem;
    font-size: var(--text-sm);
    color: var(--text-tertiary);
}

.help-view { display: none; }
.help-view--desktop { display: block; }

@media (max-width: 47.99rem) and (orientation: portrait) {
    .help-view--desktop { display: none; }
    .help-view--portrait { display: block; }
}
@media (orientation: landscape) and (max-height: 31.99rem) {
    .help-view--desktop { display: none; }
    .help-view--landscape { display: block; }
}

body.help-view-desktop .help-view,
body.help-view-portrait .help-view,
body.help-view-landscape .help-view { display: none; }
body.help-view-desktop .help-view--desktop,
body.help-view-portrait .help-view--portrait,
body.help-view-landscape .help-view--landscape { display: block; }

.help-browser {
    border: 1px solid var(--border-default);
    border-radius: var(--radius-xl);
    overflow: hidden;
    background: var(--surface-card);
    box-shadow: var(--shadow-lg);
}
.help-browser-bar {
    display: flex;
    align-items: center;
    gap: .35rem;
    padding: .5rem .75rem;
    border-bottom: 1px solid var(--border-subtle);
    background: var(--surface-inset);
}
.help-browser-bar > span:not(.help-browser-url) {
    width: .6rem;
    height: .6rem;
    border-radius: 999px;
    background: var(--border-default);
}
.help-browser-url {
    margin-left: .75rem;
    padding: .15rem .75rem;
    border-radius: 999px;
    background: var(--surface-card);
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--text-tertiary);
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.help-browser-screen { position: relative; line-height: 0; }
.help-browser-screen img { display: block; width: 100%; height: auto; }

.help-zoom { display: block; cursor: zoom-in; }
.help-zoom:focus-visible { outline-offset: -3px; }

@media (max-width: 40rem) {
    .help-viewpick { position: static; padding: .6rem .75rem; }
    .help-viewpick .help-segmented button { padding: .35rem .6rem; font-size: var(--text-xs); }
    .help-app-shot { margin-left: 0; }
    .help-browser-url { display: none; }
}

/* Callouts, tables, definitions -------------------------------------------- */

.help-note p { line-height: 1.6; }
.help-section > .help-note,
.help-section > .help-note--tip,
.help-section > .help-note--warning { margin-bottom: 1.25rem; color: var(--text-primary); }
.help-note--tip { border-left-color: var(--success-fg); background: var(--success-bg); }
.help-note--warning { border-left-color: var(--warning-fg); background: var(--warning-bg); }
.help-note b, .help-note strong { color: var(--text-primary); }

.help-table-wrap { overflow-x: auto; margin: 0 0 1.25rem; }
.help-table { width: 100%; font-size: var(--text-sm); }
.help-table th,
.help-table td {
    text-align: left;
    vertical-align: top;
    padding: .6rem .75rem;
    border-bottom: 1px solid var(--border-subtle);
    color: var(--text-secondary);
    line-height: 1.5;
}
.help-table th {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}
.help-table b { color: var(--text-primary); }

.help-defs { margin: 0 0 1.25rem; display: grid; gap: .25rem 0; }
.help-defs dt { font-weight: 600; color: var(--text-primary); margin-top: .6rem; }
.help-defs dd { margin: 0; color: var(--text-secondary); line-height: 1.6; }

.help-step-head p a,
.help-section p a,
.help-list a { text-decoration: underline; text-underline-offset: 2px; }

/* ===========================================================================
   Bilingual display.

   Only the inactive language is hidden. Showing the active one by setting
   `display` back on it would force a rule per element type (inline /
   inline-block / flex …) and fight each element's own layout.
   =========================================================================== */

body.lang-pl [lang="en"],
body.lang-en [lang="pl"] { display: none; }

/* ===========================================================================
   Motion — one curve, short travel. Things arrive and settle.
   =========================================================================== */

@keyframes rise {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
}

.rise { animation: rise var(--dur-panel) var(--ease-brand) both; }
.rise-1 { animation-delay: 40ms; }
.rise-2 { animation-delay: 100ms; }
.rise-3 { animation-delay: 160ms; }

/* Reduced-motion users lose the travel, nothing else. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}

/* Screenshot lightbox (help.js). Always dark around the image, in both themes, so the
   screenshot reads the same; above the chat bubble. */
html.help-lightbox-open { overflow: hidden; }
html.help-lightbox-open body { overflow: hidden; }

.help-lightbox {
    position: fixed;
    inset: 0;
    z-index: 2147483600;
    display: flex;
    flex-direction: column;
    background: rgba(8, 10, 16, .98);
    color: #fff;
    padding: max(.5rem, env(safe-area-inset-top)) max(.5rem, env(safe-area-inset-right)) max(.5rem, env(safe-area-inset-bottom)) max(.5rem, env(safe-area-inset-left));
}
.help-lightbox[hidden] { display: none; }

.help-lightbox-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    min-height: 2.75rem;
    padding: 0 .25rem;
}
.help-lightbox-counter { font-size: .9rem; opacity: .8; font-variant-numeric: tabular-nums; }

.help-lightbox button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    flex: none;
    border: 0;
    border-radius: 999px;
    background: rgba(255, 255, 255, .12);
    color: #fff;
    cursor: pointer;
}
.help-lightbox button:hover { background: rgba(255, 255, 255, .24); }
.help-lightbox button:focus-visible { outline: 3px solid #9bc2ff; outline-offset: 2px; }
.help-lightbox button:disabled { opacity: .3; cursor: default; }
.help-lightbox button[hidden] { display: none; }
.help-lightbox svg { width: 1.4rem; height: 1.4rem; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

.help-lightbox-stage {
    flex: 1;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
}

.help-lightbox-frame {
    position: relative;
    line-height: 0;
    max-width: min(95vw, 100%);
    min-width: 0;
}
.help-lightbox-frame img {
    display: block;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: calc(100vh - 8.5rem);
    max-height: calc(100dvh - 8.5rem);
    border-radius: .5rem;
    background: #fff;
    box-shadow: 0 1.5rem 4rem rgba(0, 0, 0, .5);
}
.help-lightbox-frame--phone img { border-radius: 1rem; }

.help-lightbox-caption {
    margin: .5rem auto 0;
    max-width: 60rem;
    text-align: center;
    font-size: .95rem;
    line-height: 1.45;
    color: rgba(255, 255, 255, .88);
    max-height: 4.4em;
    overflow: auto;
}

/* Phones: the arrows go over the image's edges, so the image keeps the full width. */
@media (max-width: 40rem), (max-height: 30rem) {
    .help-lightbox-stage { position: relative; gap: 0; }
    .help-lightbox-nav { position: absolute; top: 50%; transform: translateY(-50%); z-index: 1; background: rgba(8, 10, 16, .6) !important; }
    .help-lightbox-prev { left: .25rem; }
    .help-lightbox-next { right: .25rem; }
    .help-lightbox-frame { max-width: 100%; }
}
@media (max-height: 30rem) {
    .help-lightbox-bar { min-height: 2.5rem; position: absolute; top: .25rem; right: .25rem; left: .25rem; z-index: 2; }
    .help-lightbox-frame img { max-height: calc(100vh - 3.5rem); max-height: calc(100dvh - 3.5rem); }
    .help-lightbox-caption { margin-top: .25rem; max-height: 1.6em; font-size: .85rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
}
