/* ===========================================================================
   Gym Buddy AI
   Shared stylesheet for /gymbuddy, /gymbuddy/documentation,
   /gymbuddy/privacy_policy, /gymbuddy/disclaimer.

   Design intent: the app itself, at desktop size. Soft lilac ground, white
   cards with a purple accent, one gradient (the app bar and hero card), and
   a friendly, direct tone. Numbers are set in mono so sets, reps and kilos
   read like a training log.

   Colour tokens are lifted from gym_buddy/lib/config/palette.dart so the site
   and the app cannot drift.
   =========================================================================== */

*,
*::before,
*::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

:root {
    color-scheme: light;

    /* == Colour: straight from palette.dart == */
    --purple:       #800080;   /* kPrimaryColour     6.7:1 on --bg            */
    --purple-deep:  #5C005C;   /* kPrimaryDark, headings                      */
    --purple-light: #B24DB2;   /* kPrimaryLight  DECORATIVE ONLY (3.4:1)      */
    --grad-a:       #9C27B0;   /* kGradientColours[0]                          */
    --bg:           #F8F6FA;   /* kBackgroundColour                            */
    --surface:      #FFFFFF;   /* kCardColour                                  */
    --tint:         #F1EAF4;   /* kSurfaceTint                                 */
    --success:      #2E9E5B;
    --success-text: #1F7A44;   /* success darkened so it can carry text        */
    --warning:      #E08A17;
    --warning-text: #9A5A05;
    --danger:       #E5484D;
    --danger-text:  #B4232A;

    /* neutrals */
    --ink:       #1C1B1F;      /* kTextColour                                  */
    --ink-soft:  #6B6572;      /* kTextSecondary                               */
    --line:      #E6DFEA;
    --tint-purple:  rgba(128, 0, 128, .08);
    --tint-success: rgba(46, 158, 91, .10);
    --tint-warning: rgba(224, 138, 23, .12);
    --tint-danger:  rgba(229, 72, 77, .09);

    /* == Typography == */
    --font-sans: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --font-mono: 'IBM Plex Mono', 'SF Mono', Consolas, monospace;

    --fs-hero:    clamp(2.2rem, 4.5vw, 3.4rem);
    --fs-h2:      clamp(1.6rem, 3vw, 2.1rem);
    --fs-h3:      1.25rem;
    --fs-body:    1.0625rem;
    --fs-small:   .9375rem;
    --fs-label:   .8125rem;
    --fs-readout: clamp(2.4rem, 5vw, 3.5rem);

    /* == Spacing == */
    --s-1: .5rem;  --s-2: 1rem;   --s-3: 1.5rem;  --s-4: 2rem;
    --s-5: 3rem;   --s-6: 4.5rem; --s-7: 7rem;
    --max: 1120px;
    --pad: clamp(20px, 5vw, 40px);
    --nav-h: 68px;

    /* == Radii: the app uses 20-28 on cards and dialogs == */
    --r-sm: 10px; --r-md: 14px; --r-lg: 20px; --r-xl: 28px; --r-full: 999px;

    /* == Shadows: purple-tinted, like the app's card shadows == */
    --shadow-sm: 0 1px 3px rgba(92, 0, 92, .07);
    --shadow-md: 0 6px 20px rgba(92, 0, 92, .10);
    --shadow-lg: 0 16px 40px rgba(128, 0, 128, .16);
    --glow:      0 8px 28px rgba(128, 0, 128, .28);

    /* == Motion == */
    --ease:   cubic-bezier(.4, 0, .2, 1);
    --t-fast: 160ms var(--ease);
    --t-base: 280ms var(--ease);
    --t-slow: 500ms var(--ease);
}

/* --------------------------------------------------------------- base ---- */

html {
    -webkit-text-size-adjust: 100%;
}

@media (prefers-reduced-motion: no-preference) {
    html { scroll-behavior: smooth; }
}

body {
    font-family: var(--font-sans);
    font-size: var(--fs-body);
    line-height: 1.65;
    color: var(--ink);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    overflow-x: hidden;
}

h1, h2, h3, h4 {
    line-height: 1.2;
    color: var(--purple-deep);
    font-weight: 700;
    letter-spacing: -.015em;
}

h1 { font-size: var(--fs-hero); line-height: 1.1; letter-spacing: -.02em; }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); }

p { color: var(--ink-soft); }

a { color: var(--purple); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--purple-deep); }

:focus-visible {
    outline: 2px solid var(--purple);
    outline-offset: 3px;
    border-radius: 3px;
}

[id] { scroll-margin-top: calc(var(--nav-h) + 24px); }

.container {
    width: 100%;
    max-width: var(--max);
    margin-inline: auto;
    padding-inline: var(--pad);
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 200;
    background: var(--purple);
    color: #fff;
    padding: .75rem 1.25rem;
    border-radius: 0 0 var(--r-sm) 0;
    font-weight: 600;
}
.skip-link:focus {
    left: 0;
    color: #fff;
}

.mono {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
}

.label {
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--ink-soft);
}

.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* ---------------------------------------------------------------- nav ---- */

.site-header {
    position: sticky;
    top: 0;
    z-index: 100;
    background: rgba(248, 246, 250, .82);
    transition: background var(--t-fast), box-shadow var(--t-fast), border-color var(--t-fast);
    border-bottom: 1px solid transparent;
}
.site-header.scrolled {
    background: rgba(255, 255, 255, .92);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    backdrop-filter: saturate(180%) blur(14px);
    border-bottom-color: var(--line);
    box-shadow: var(--shadow-sm);
}

.nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-2);
    height: var(--nav-h);
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: .6rem;
    text-decoration: none;
    flex-shrink: 0;
}
.brand img { display: block; width: 32px; height: 32px; border-radius: 8px; }
.brand-name {
    font-weight: 700;
    font-size: 1.0625rem;
    letter-spacing: -.01em;
    color: var(--purple-deep);
}

.nav-links {
    display: flex;
    align-items: center;
    gap: .35rem;
}
.nav-links a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 .75rem;
    border-radius: var(--r-sm);
    font-size: var(--fs-small);
    font-weight: 500;
    color: var(--ink-soft);
    text-decoration: none;
    white-space: nowrap;
    transition: color var(--t-fast), background var(--t-fast);
}
.nav-links a:hover { color: var(--purple); background: var(--tint-purple); }
.nav-links a[aria-current="page"] { color: var(--purple); font-weight: 600; }

/* Nav call to action: the App Store link as a filled purple pill. */
.nav-cta {
    display: inline-flex;
    align-items: center;
    min-height: 38px;
    margin-left: .4rem;
    padding: 0 1.05rem;
    border-radius: var(--r-full);
    background: var(--purple);
    color: #fff;
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    letter-spacing: .06em;
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
    transition: background .2s ease, transform .2s ease;
}
.nav-cta:hover {
    background: var(--purple-deep);
    transform: translateY(-1px);
}
.nav-links a.nav-cta { color: #fff; }

.nav-toggle {
    display: none;
    width: 44px; height: 44px;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    background: var(--surface);
    cursor: pointer;
}
.nav-toggle span {
    display: block;
    position: relative;
    width: 18px; height: 1.5px;
    background: var(--purple-deep);
    transition: transform var(--t-fast), background var(--t-fast);
}
.nav-toggle span::before,
.nav-toggle span::after {
    content: "";
    position: absolute;
    left: 0;
    width: 18px; height: 1.5px;
    background: var(--purple-deep);
    transition: transform var(--t-fast), top var(--t-fast);
}
.nav-toggle span::before { top: -6px; }
.nav-toggle span::after  { top:  6px; }
.nav-toggle[aria-expanded="true"] span { background: transparent; }
.nav-toggle[aria-expanded="true"] span::before { top: 0; transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] span::after  { top: 0; transform: rotate(-45deg); }

/* ------------------------------------------------------------ sections --- */

.section { padding-block: var(--s-6); }
.section-tight { padding-block: var(--s-5); }

.section-head { max-width: 62ch; margin-bottom: var(--s-4); }
.section-head p { margin-top: .6rem; }

/* Set rule. The section divider is a row of set dots, the same motif the app
   uses under each exercise: filled where done, hollow where still to go. */
.set-rule {
    display: flex;
    align-items: center;
    gap: 10px;
    height: 22px;
}
.set-rule::before {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--line);
}
.set-rule::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--line);
}
.set-rule i {
    display: block;
    width: 9px; height: 9px;
    border-radius: 50%;
    border: 1.5px solid var(--purple-light);
    background: transparent;
}
.set-rule i.done { background: var(--purple); border-color: var(--purple); }

/* ---------------------------------------------------------------- hero --- */

.hero {
    position: relative;
    padding-top: var(--s-6);
    padding-bottom: var(--s-4);
    overflow: hidden;
}
.hero::before {
    /* soft lilac wash, the app's surface tint */
    content: "";
    position: absolute;
    inset: -20% 40% 40% -10%;
    background: radial-gradient(closest-side, rgba(178, 77, 178, .20), transparent 70%);
    pointer-events: none;
    z-index: -1;
}

.hero-grid {
    display: grid;
    grid-template-columns: 1.05fr .95fr;
    gap: var(--s-5);
    align-items: center;
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .3rem .75rem;
    border-radius: var(--r-full);
    border: 1px solid rgba(128, 0, 128, .22);
    background: var(--tint-purple);
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--purple);
}

.hero h1 { margin: var(--s-2) 0 var(--s-2); }
.hero-sub { font-size: 1.125rem; max-width: 54ch; }

.hero-cta {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
    margin-top: var(--s-3);
}

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    min-height: 48px;
    padding: 0 1.4rem;
    border-radius: var(--r-full);
    font-family: var(--font-sans);
    font-size: var(--fs-small);
    font-weight: 600;
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
    transition: transform var(--t-fast), box-shadow var(--t-fast),
                background var(--t-fast), color var(--t-fast);
}
.btn-primary {
    background: var(--purple);
    color: #fff;
    box-shadow: var(--glow);
}
.btn-primary:hover {
    background: var(--purple-deep);
    color: #fff;
    transform: translateY(-1px);
}
.btn-ghost {
    background: var(--surface);
    color: var(--purple);
    border-color: rgba(128, 0, 128, .28);
}
.btn-ghost:hover { background: var(--tint-purple); color: var(--purple-deep); }

/* Readout strip */
.readouts {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--s-3);
    margin-top: var(--s-5);
    padding-top: var(--s-3);
    border-top: 1px solid var(--line);
}
.readout .n {
    display: block;
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 1.75rem;
    font-weight: 500;
    color: var(--purple-deep);
    line-height: 1.1;
}
.readout .n small {
    font-size: .5em;
    color: var(--ink-soft);
    margin-left: .15em;
}
.readout .t {
    display: block;
    font-size: var(--fs-label);
    color: var(--ink-soft);
    margin-top: .35rem;
}

/* Hero figure: a phone frame holding the home screenshot. */
.hero-figure {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
}
/* Rhino waves from beside the phone, the way he greets you on the app's
   loading screen. Positioned against .hero-figure, so he tracks the phone
   rather than the page centre. */
.hero-rhino {
    /* Transparent explicitly, and never a lazy image: a filtered element
       whose image is still decoding can paint its layer's backing, which
       showed as a grey box around him on first paint and repainted away as
       soon as you scrolled. He is above the fold, so he loads with the page
       and decodes before it. */
    background-color: transparent;
    position: absolute;
    bottom: -10px;
    /* His right edge sits just inside the phone's left bezel, whatever the
       column is doing: the phone is 300px and centred, so half of it is
       150px, and 128 leaves him overlapping the frame but never the screen,
       which is where his raised arm would otherwise disappear. */
    right: calc(50% + 128px);
    width: auto;
    height: 210px;
    z-index: 2;
    filter: drop-shadow(0 16px 24px rgba(46, 0, 46, .45));
    pointer-events: none;
}
.hero-phone {
    width: 100%;
    max-width: 300px;
    padding: 10px;
    background: var(--ink);
    border-radius: 48px;
    box-shadow: var(--shadow-lg), 0 0 0 1px rgba(0, 0, 0, .06);
    position: relative;
    overflow: hidden;
}
/* No drawn island in either frame. Every screenshot is a real device capture
   and carries its own Dynamic Island, status bar and home indicator; a second
   one painted on top never lined up with it, so the real island showed from
   under the fake pill on the hero and the shots wore a pale bar across the
   top. The frame is the bezel only. */
.hero-phone img {
    display: block;
    /* The ratio lives on the image, never on the padded frame: a percentage
       height against an aspect-ratio parent resolves against the BORDER box
       in WebKit, so the image ran 20px long, overflowed the bottom bezel and
       got clipped square by overflow:hidden. height:auto + aspect-ratio is
       resolved identically by every engine. */
    width: 100%; height: auto;
    aspect-ratio: 1320 / 2868;
    object-fit: cover;
    border-radius: 38px;
    background: var(--bg);
}

/* ------------------------------------------------------------- steps ----- */

.steps {
    display: grid;
    gap: var(--s-3);
}
.step {
    display: grid;
    grid-template-columns: 46px 1fr;
    gap: var(--s-3);
    align-items: start;
    padding: var(--s-3);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
}
.step-n {
    display: grid;
    place-items: center;
    width: 46px; height: 46px;
    border-radius: var(--r-full);
    background: var(--tint-purple);
    border: 1px solid rgba(128, 0, 128, .2);
    font-family: var(--font-mono);
    font-size: 1.05rem;
    font-weight: 500;
    color: var(--purple);
}
.step h3 { margin-bottom: .4rem; }
.step p { font-size: var(--fs-small); }

/* Small status chips, coloured the way the app colours them. */
.mode-chip {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    margin-bottom: .55rem;
    padding: .2rem .6rem;
    border-radius: var(--r-sm);
    font-family: var(--font-mono);
    font-size: .6875rem;
    letter-spacing: .07em;
    text-transform: uppercase;
    font-weight: 500;
}
.mode-chip::before {
    content: "";
    width: 8px; height: 8px;
    border-radius: 50%;
    background: currentColor;
}
.mode-rhino {
    background: var(--tint-purple);
    color: var(--purple);
    border: 1px solid rgba(128, 0, 128, .3);
}
.mode-done {
    background: var(--tint-success);
    color: var(--success-text);
    border: 1px solid rgba(46, 158, 91, .35);
}
.mode-streak {
    background: var(--tint-warning);
    color: var(--warning-text);
    border: 1px solid rgba(224, 138, 23, .35);
}

/* ---------------------------------------------------------- feature grid - */

.grid-cards {
    display: grid;
    /* Wider columns and one line of copy per card: ten cards of ragged
       paragraphs read as a wall of text, whoever is scrolling. The long
       version of each lives on the documentation page. */
    /* Explicit counts rather than auto-fit, because the orphan rules below
       have to know how many columns there are. */
    grid-template-columns: 1fr;
    gap: var(--s-3);
    align-items: stretch;
}
@media (min-width: 640px) {
    .grid-cards { grid-template-columns: repeat(2, 1fr); }
    /* A card left alone on the last row reads as a mistake rather than a
       list that ended. If the count is one past a full row, the last card
       spans instead of hanging: with nine cards that is the two-column
       layout, and it closes the section rather than dangling in it. */
    .grid-cards .card:last-child:nth-child(2n + 1) { grid-column: 1 / -1; }
}
@media (min-width: 1000px) {
    .grid-cards { grid-template-columns: repeat(3, 1fr); }
    .grid-cards .card:last-child:nth-child(2n + 1) { grid-column: auto; }
    .grid-cards .card:last-child:nth-child(3n + 1) { grid-column: 1 / -1; }
}
.grid-cards .card p {
    /* the claim, not the manual */
    margin: 0;
    max-width: 46ch;
}
.card {
    padding: var(--s-3);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
    transition: transform var(--t-base), box-shadow var(--t-base),
                border-color var(--t-base);
}
.card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-md);
    border-color: rgba(128, 0, 128, .25);
}
.card-icon {
    display: grid;
    place-items: center;
    width: 44px; height: 44px;
    margin-bottom: var(--s-2);
    border-radius: var(--r-md);
    background: var(--tint-purple);
    color: var(--purple);
}
.card-icon svg { width: 22px; height: 22px; }
.card h3 { margin-bottom: .45rem; font-size: 1.0625rem; }
.card p { font-size: var(--fs-small); }

/* ------------------------------------------------------------ rhino band - */
/* Rhino himself, introduced at something like life size: he is the mascot and
   half the store name, so the band leads with the animal rather than a
   heading. Sized by height; the width falls out of the pose. */
.rhino-mascot {
    background-color: transparent;
    display: block;
    height: 340px;
    width: auto;
    margin-bottom: var(--s-2);
    filter: drop-shadow(0 14px 22px rgba(92, 0, 92, .20));
}

.rhino-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--s-5);
    align-items: center;
}

/* A short chat transcript, styled like ChatBubble in the app. */
.chat {
    display: grid;
    min-width: 0;
    gap: .75rem;
    padding: var(--s-3);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-xl);
    box-shadow: var(--shadow-md);
}
.bubble {
    max-width: 88%;
    /* Grid items default to min-width:auto, so the nowrap table below set a
       min-content floor (~425px) that the page could never shrink under: on a
       390px phone the document overflowed, Safari zoomed out to fit, and the
       sticky header stopped spanning the scrolled width. */
    min-width: 0;
    padding: .75rem 1rem;
    border-radius: 18px;
    font-size: var(--fs-small);
    line-height: 1.5;
}
.bubble-user {
    justify-self: end;
    background: var(--purple);
    color: #fff;
    border-bottom-right-radius: 6px;
}
.bubble-rhino {
    justify-self: start;
    background: var(--tint);
    color: var(--ink);
    border-bottom-left-radius: 6px;
}
.bubble-rhino p { color: var(--ink); margin: 0 0 .5rem; }
.bubble-rhino p:last-child { margin-bottom: 0; }
/* Rhino's turns carry his avatar, exactly as the app's ChatBubble draws them. */
.msg-rhino {
    display: flex;
    align-items: flex-end;
    gap: .5rem;
    min-width: 0;
    max-width: 88%;
}
.msg-rhino .bubble { max-width: 100%; }
.avatar {
    flex-shrink: 0;
    width: 34px; height: 34px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--tint);
    box-shadow: 0 0 0 1px var(--line);
}
/* The table keeps its nowrap cells; it scrolls inside the bubble instead of
   widening the page. */
.table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border-radius: var(--r-sm);
}
.bubble table {
    width: 100%;
    border-collapse: collapse;
    font-family: var(--font-mono);
    font-size: .8125rem;
    background: var(--surface);
    border-radius: var(--r-sm);
    overflow: hidden;
}
.bubble th, .bubble td {
    text-align: left;
    padding: .4rem .6rem;
    border-bottom: 1px solid var(--line);
    white-space: nowrap;
}
.bubble th {
    background: var(--tint-purple);
    color: var(--purple-deep);
    font-weight: 600;
}
.bubble tr:last-child td { border-bottom: 0; }
.bubble-meta {
    font-family: var(--font-mono);
    font-size: .6875rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ink-soft);
    margin-top: .1rem;
}
.bubble-meta.right { text-align: right; }

/* honesty panel */
.note-panel {
    display: flex;
    gap: var(--s-2);
    align-items: flex-start;
    margin-top: var(--s-4);
    padding: var(--s-3);
    background: var(--tint-purple);
    border: 1px solid rgba(128, 0, 128, .2);
    border-radius: var(--r-md);
}
.note-panel svg { flex-shrink: 0; width: 20px; height: 20px; color: var(--purple); margin-top: 2px; }
.note-panel p { font-size: var(--fs-small); color: var(--purple-deep); }

/* ------------------------------------------------------------ screenshots - */

.shots {
    display: flex;
    gap: var(--s-3);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding-block: var(--s-2) var(--s-3);
    scrollbar-width: thin;
    scrollbar-color: var(--purple-light) transparent;
}
.shots::-webkit-scrollbar { height: 8px; }
.shots::-webkit-scrollbar-track { background: var(--line); border-radius: var(--r-full); }
.shots::-webkit-scrollbar-thumb { background: var(--purple-light); border-radius: var(--r-full); }

.shot {
    flex: 0 0 auto;
    width: 230px;
    scroll-snap-align: center;
    text-align: center;
}
.shot-frame {
    position: relative;
    padding: 9px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 40px;
    box-shadow: var(--shadow-md);
    overflow: hidden;
}
.shot-frame img {
    position: relative;
    z-index: 1;
    display: block;
    /* see .hero-phone img - the ratio belongs on the image */
    width: 100%; height: auto;
    aspect-ratio: 1320 / 2868;
    object-fit: cover;
    border-radius: 31px;
}
.shot-fallback {
    position: absolute;
    inset: 9px;
    z-index: 0;
    display: grid;
    place-content: center;
    gap: .75rem;
    justify-items: center;
    border-radius: 31px;
    border: 1px dashed rgba(128, 0, 128, .3);
    background: linear-gradient(160deg, var(--tint-purple), var(--bg) 65%);
    text-align: center;
    padding: 1rem;
}
.shot-fallback img { width: 56px; height: 56px; opacity: .35; border-radius: 12px; }
.shot-fallback .fn {
    font-family: var(--font-mono);
    font-size: .6875rem;
    line-height: 1.5;
    color: var(--ink-soft);
    word-break: break-all;
}
.shot figcaption {
    margin-top: .75rem;
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    letter-spacing: .05em;
    color: var(--ink-soft);
}

/* ------------------------------------------------------------- band ------ */

/* The closing card: the app's gradient app bar, at full width. */
.soon-card {
    position: relative;
    isolation: isolate;
    padding: var(--s-5) var(--s-4);
    border-radius: var(--r-xl);
    background: linear-gradient(135deg, var(--grad-a) 0%, var(--purple) 55%, var(--purple-deep) 100%);
    box-shadow: var(--glow);
    color: #fff;
    text-align: center;
    overflow: hidden;
}
.soon-card h2 { color: #fff; }
.soon-card .rhino-mascot {
    height: 240px;
    margin: 0 auto var(--s-2);
    filter: drop-shadow(0 14px 24px rgba(0, 0, 0, .34));
}
.soon-card p {
    color: rgba(255, 255, 255, .94);
    max-width: 52ch;
    margin: .75rem auto var(--s-3);
}
.soon-card .btn-ghost {
    background: #fff;
    color: var(--purple);
    border-color: transparent;
}
.soon-card .btn-ghost:hover { background: rgba(255, 255, 255, .9); color: var(--purple-deep); }

/* ---------------------------------------------------------------- prose --- */

.prose-page { padding-block: var(--s-5) var(--s-6); }
.prose { max-width: 760px; margin-inline: auto; }
.prose h1 { margin-bottom: .5rem; }
.prose > .label { display: block; margin-bottom: var(--s-4); }
.prose h2 {
    margin-top: var(--s-5);
    margin-bottom: var(--s-2);
    padding-top: var(--s-2);
    border-top: 1px solid var(--line);
    font-size: 1.375rem;
}
.prose h3 { margin-top: var(--s-3); margin-bottom: .5rem; font-size: 1.0625rem; }
.prose p { margin-bottom: var(--s-2); }
.prose ul, .prose ol { margin: 0 0 var(--s-2) 1.25rem; }
.prose li { margin-bottom: .6rem; color: var(--ink-soft); }
.prose li strong { color: var(--purple-deep); }
.prose dl { margin-bottom: var(--s-2); }
.prose dt { font-weight: 600; color: var(--purple-deep); margin-top: var(--s-2); }
.prose dd { margin-left: 0; color: var(--ink-soft); }

.callout {
    padding: var(--s-3);
    margin-bottom: var(--s-3);
    background: var(--tint-purple);
    border: 1px solid rgba(128, 0, 128, .22);
    border-left: 3px solid var(--purple);
    border-radius: var(--r-md);
}
.callout p { color: var(--purple-deep); margin-bottom: 0; }
.callout-warn {
    background: var(--tint-danger);
    border-color: rgba(229, 72, 77, .28);
    border-left-color: var(--danger);
}
.callout-warn p { color: #7A1A1E; }

/* --------------------------------------------------------------- docs ----- */

.docs-layout {
    display: grid;
    grid-template-columns: 240px 1fr;
    gap: var(--s-5);
    align-items: start;
}
.docs-nav {
    position: sticky;
    top: calc(var(--nav-h) + 20px);
    max-height: calc(100vh - var(--nav-h) - 40px);
    overflow-y: auto;
}
.docs-nav ol { list-style: none; margin: 0; padding: 0; }
.docs-nav li { margin: 0; }
.docs-nav a {
    display: block;
    padding: .4rem .7rem;
    border-left: 2px solid var(--line);
    font-size: var(--fs-small);
    color: var(--ink-soft);
    text-decoration: none;
    transition: color var(--t-fast), border-color var(--t-fast), background var(--t-fast);
}
.docs-nav a:hover { color: var(--purple); background: var(--tint-purple); }
.docs-nav a[aria-current="true"] {
    color: var(--purple);
    font-weight: 600;
    border-left-color: var(--purple);
    background: var(--tint-purple);
}
.docs-summary { display: none; }

.docs-body section { margin-bottom: var(--s-5); }
.docs-body h2 {
    margin-bottom: var(--s-2);
    padding-bottom: .5rem;
    border-bottom: 1px solid var(--line);
    font-size: 1.5rem;
}
.docs-body h3 { margin-top: var(--s-3); margin-bottom: .5rem; }
.docs-body p { margin-bottom: var(--s-2); }
.docs-body ul, .docs-body ol { margin: 0 0 var(--s-2) 1.25rem; }
.docs-body li { margin-bottom: .5rem; color: var(--ink-soft); }
.docs-body li strong { color: var(--purple-deep); }

.kv {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: var(--s-2);
    font-size: var(--fs-small);
}
.kv th, .kv td {
    text-align: left;
    padding: .6rem .75rem;
    border-bottom: 1px solid var(--line);
    vertical-align: top;
}
.kv th {
    width: 34%;
    color: var(--purple-deep);
    font-weight: 600;
}
.kv td { color: var(--ink-soft); }
.kv tr:last-child th, .kv tr:last-child td { border-bottom: 0; }
.table-wrap { overflow-x: auto; }

/* Bullet motif: a set dot, ticked. */
.dot-list { list-style: none; margin-left: 0 !important; }
.dot-list li {
    position: relative;
    padding-left: 1.5rem;
}
.dot-list li::before {
    content: "";
    position: absolute;
    left: 0; top: .5em;
    width: 11px; height: 11px;
    border-radius: 50%;
    background: var(--purple);
}
.dot-list-danger li::before { background: var(--danger); }

/* -------------------------------------------------------------- footer ---- */

.site-footer {
    margin-top: var(--s-6);
    padding-block: var(--s-5) var(--s-3);
    background: var(--surface);
    border-top: 1px solid var(--line);
}
.footer-grid {
    display: grid;
    grid-template-columns: 1.4fr 1fr 1fr 1fr;
    gap: var(--s-4);
}
.footer-brand img { width: 36px; height: 36px; border-radius: 9px; margin-bottom: .6rem; }
.footer-brand .brand-name { display: block; margin-bottom: .4rem; }
.footer-brand p { font-size: var(--fs-small); max-width: 34ch; }
.footer-col h3 {
    margin-bottom: .75rem;
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--ink-soft);
    font-weight: 500;
}
.footer-col ul { list-style: none; }
.footer-col li { margin-bottom: .45rem; }
.footer-col a {
    font-size: var(--fs-small);
    color: var(--ink-soft);
    text-decoration: none;
}
.footer-col a:hover { color: var(--purple); text-decoration: underline; }
.footer-bottom {
    margin-top: var(--s-4);
    padding-top: var(--s-3);
    border-top: 1px solid var(--line);
    display: flex;
    flex-wrap: wrap;
    gap: .5rem var(--s-3);
    justify-content: space-between;
    align-items: center;
}
.footer-bottom p { font-size: var(--fs-label); color: var(--ink-soft); }

/* --------------------------------------------------- shared workout page -- */

/* /gymbuddy/w. Mobile first: this page is nearly always opened by tapping a
   link or scanning a QR code on a phone, so the column is narrow, the exercise
   cards stack, and the two buttons come before the workout. Everything is
   drawn by share.js from the URL fragment. */

.share-page { padding-block: var(--s-4) var(--s-5); }
.share-wrap { max-width: 620px; }

.share-head { text-align: center; }
.share-icon {
    width: 76px; height: 76px;
    border-radius: 18px;
    box-shadow: var(--shadow-md);
    margin-bottom: var(--s-2);
}
.share-head .label { display: block; margin-bottom: .35rem; }
.share-head h1 {
    font-size: clamp(1.75rem, 6vw, 2.5rem);
    overflow-wrap: anywhere;
}
.share-summary { margin-top: .5rem; text-transform: none; letter-spacing: .04em; }

.share-cta { justify-content: center; margin-top: var(--s-3); }
.share-cta .btn { flex: 1 1 240px; max-width: 320px; }

.share-note {
    margin: var(--s-3) auto 0;
    max-width: 44ch;
    font-size: var(--fs-label);
    line-height: 1.55;
}

.share-page .set-rule { margin-block: var(--s-4); }
.share-loading { text-align: center; font-size: var(--fs-small); }

.share-foot {
    margin-top: var(--s-4);
    padding-top: var(--s-3);
    border-top: 1px solid var(--line);
    font-size: var(--fs-small);
    text-align: center;
}

/* Exercise cards. The superset connector is the visual echo of the link icon
   in the app's editor: the pair is drawn as one run. */
.ex-list { list-style: none; display: grid; gap: var(--s-2); }
.ex-item { display: grid; }
.ex-card { padding: var(--s-2) var(--s-3) var(--s-3); }
.ex-card:hover { transform: none; box-shadow: var(--shadow-sm); border-color: var(--line); }

.ex-top {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    justify-content: space-between;
    margin-top: .4rem;
}
.ex-name {
    display: flex;
    align-items: baseline;
    gap: .6rem;
    font-size: 1.0625rem;
    line-height: 1.3;
    overflow-wrap: anywhere;
}
.ex-n {
    flex: none;
    min-width: 1.6em;
    color: var(--purple-light);
    font-size: var(--fs-label);
}
.ex-type { flex: none; padding: .15rem .55rem; font-size: .6875rem; }
.ex-meta { margin-top: .3rem; }
.ex-note {
    margin-top: .6rem;
    padding-left: .75rem;
    border-left: 2px solid var(--line);
    font-size: var(--fs-small);
    overflow-wrap: anywhere;
}

.ex-card .table-wrap { margin-top: var(--s-2); }
.set-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--fs-small);
}
.set-table th, .set-table td {
    text-align: left;
    padding: .45rem .6rem;
    border-bottom: 1px solid var(--line);
    white-space: nowrap;
}
.set-table thead th {
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--ink-soft);
    font-weight: 500;
}
.set-table tbody th { color: var(--purple-light); font-weight: 500; width: 3.5rem; }
.set-table tbody td { color: var(--ink); }
.set-table tr:last-child th, .set-table tr:last-child td { border-bottom: 0; }
.set-table .set-blank { color: var(--ink-soft); }
.set-table .bodyweight {
    font-family: var(--font-sans);
    font-size: var(--fs-label);
    color: var(--success-text);
}

.superset-link {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding-left: var(--s-3);
    height: 26px;
    margin-top: -.25rem;
}
.superset-link::before {
    content: "";
    width: 2px;
    height: 100%;
    background: var(--purple-light);
    border-radius: 1px;
}
.superset-tag {
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--purple);
}

/* ?selftest output */
.selftest-out {
    padding: var(--s-2);
    background: var(--surface);
    border: 1px solid var(--line);
    border-left: 3px solid var(--ink-soft);
    border-radius: var(--r-md);
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    line-height: 1.7;
    white-space: pre;
    overflow-x: auto;
}
.selftest-out.selftest-ok  { border-left-color: var(--success); }
.selftest-out.selftest-bad { border-left-color: var(--danger); }

@media (min-width: 620px) {
    .share-page { padding-block: var(--s-5) var(--s-6); }
    .ex-list { gap: var(--s-3); }
}

/* --------------------------------------------------------------- reveal --- */

.reveal {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity var(--t-slow), transform var(--t-slow);
}
.reveal.in { opacity: 1; transform: none; }

/* ---------------------------------------------------------- breakpoints --- */

@media (max-width: 960px) {
    .hero-grid { grid-template-columns: 1fr; gap: var(--s-4); }
    .hero-figure { order: -1; }
    .hero-phone { max-width: 240px; }
    /* Beside a 240px phone there is no room for him; he leads the rhino band
       instead, which is where the section is about him anyway. */
    .hero-rhino { display: none; }
    .rhino-mascot { height: 230px; }
    .soon-card .rhino-mascot { height: 180px; }
    .rhino-grid { grid-template-columns: 1fr; gap: var(--s-4); }

    .docs-layout { grid-template-columns: 1fr; gap: var(--s-3); }
    .docs-nav {
        position: static;
        max-height: none;
        border: 1px solid var(--line);
        border-radius: var(--r-md);
        background: var(--surface);
        padding: .5rem;
    }
    .docs-summary {
        display: block;
        cursor: pointer;
        padding: .6rem;
        font-family: var(--font-mono);
        font-size: var(--fs-label);
        text-transform: uppercase;
        letter-spacing: .08em;
        color: var(--purple);
    }
    .docs-nav a { border-left: 0; padding-left: .7rem; }
    .footer-grid { grid-template-columns: 1fr 1fr; }

    .nav-toggle { display: inline-flex; }
    .nav-links {
        position: absolute;
        left: 0; right: 0; top: var(--nav-h);
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        padding: var(--s-2) var(--pad) var(--s-3);
        background: var(--surface);
        border-bottom: 1px solid var(--line);
        box-shadow: var(--shadow-md);
        transform: translateY(-8px);
        opacity: 0;
        visibility: hidden;
        transition: opacity var(--t-fast), transform var(--t-fast), visibility var(--t-fast);
    }
    .nav-links.open { transform: none; opacity: 1; visibility: visible; }
    .nav-links a { justify-content: flex-start; }
    .nav-cta { margin: .5rem 0 0; align-self: flex-start; }
}

@media (max-width: 760px) {
    .readouts { grid-template-columns: 1fr; gap: var(--s-2); }
    .step { grid-template-columns: 38px 1fr; gap: var(--s-2); }
    .step-n { width: 38px; height: 38px; font-size: .9rem; }
    .bubble { max-width: 100%; }
}

@media (max-width: 480px) {
    .footer-grid { grid-template-columns: 1fr; }
    .shot { width: 200px; }
    .section { padding-block: var(--s-5); }
}

/* ------------------------------------------------------- reduced motion --- */

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
    .reveal { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------- print --- */

@media print {
    .site-header, .site-footer, .shots, .hero-figure, .nav-toggle { display: none; }
    body { background: #fff; color: #000; }
    .prose, .docs-body { max-width: none; }
}
