/* ===========================================================================
   ClubHQ.cloud — built on the ClubHQ 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 — the "Offset H": left stem planted, right stem raised 8
   units, crossbar swept upward between them. Ink comes from currentColor and
   the offset stem from --chq-mark-accent, so a tone is just a pair of CSS
   values. Per the brand's handoff rules the mark is never recoloured
   stem-by-stem outside this palette, never outlined, and never rotated.
   =========================================================================== */

.lockup {
    display: inline-flex;
    align-items: center;
    gap: .42em;
    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: .62em;
    letter-spacing: -.03em;
    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="ClubHQ", 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: var(--color-accent-on-dark); }

/* ===========================================================================
   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: .75rem;
    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;
    gap: .75rem;
}

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

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

.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 {
    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 { color: var(--on-ink-3); }

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

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

.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) {
    .hero-grid { grid-template-columns: 1.05fr .95fr; }
}

.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-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);
    overflow: hidden;
}

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

.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. */
    min-width: 58rem;
    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);
}

.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;
}

/* The two AI-only rows carry a short line of explanation, because "AI
   assistant" on its own does not tell a coach what changes on a Sunday
   evening. Everything above them is self-evident and gets no note. */
.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; }

/* 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; }

/* 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;
}

@media (max-width: 40rem) {
    .plan-table .row-note { display: none; }
}

.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; }

/* ===========================================================================
   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;
    }
}
