/* ============================================================================
   FlightsTaken.com — design system
   ----------------------------------------------------------------------------
   One stylesheet, no build step, no remote assets, no inline styles (strict CSP).
   Written mobile-first: the base rules are the phone layout, and every
   @media block is min-width. Three deliberate breakpoints:

     base   .. 639px   phone      one column, nav drawer, tables restack
     640px  .. 1023px  tablet     two-up grids, nav still drawered
     1024px ..         desktop    inline nav, main + rail layouts
     1240px ..         wide       full 1360px container, text inset, 5/6/7-up strips

   Visual language taken from the four mockups:
     - white cards on a near-white page, separated by a 1px #E6EAF0 hairline
       plus a whisper of shadow. Never a heavy drop shadow.
     - 14px card radius, 12px control radius, 10px button radius.
     - 24px card padding, 20-24px between cards, 40px between page sections.
     - outline icons (1.8 stroke on a 24 viewBox) in slate; solid fills reserved
       for the brand mark, the dark stat bar, stars and the verified rosette.
     - dark navy nav, dark navy stat bar, tinted marketing band, everything else
       white-on-white held together by hairlines.
   ========================================================================== */

/* ------------------------------------------------------------------ tokens */

:root {
    /* brand ------------------------------------------------------------ */
    --blue:        #0d5ce2;
    --blue-hover:  #0a4bbd;
    --blue-bright: #1668ee;   /* brand mark, icons on dark */
    --blue-ink:    #0b5cf5;   /* inline links */
    --blue-soft:   #eef4fe;
    --blue-soft-2: #e6eefc;
    --blue-line:   #cddef9;

    --navy:        #001229;   /* app bar */
    --navy-2:      #02182f;   /* marketing stat bar */
    --navy-3:      #0b2a45;

    /* surfaces --------------------------------------------------------- */
    --bg:          #fbfcfd;
    --bg-tint:     #f8fafc;   /* table header band */
    --band:        #f0f4fb;   /* marketing testimonial band */
    --card:        #ffffff;
    --chip:        #eff4fd;   /* tinted thumbnail chip */
    --level-bg:    #f2f6fd;

    /* hairlines -------------------------------------------------------- */
    --line:        #e6eaf0;   /* card border */
    --line-strong: #dde1e7;   /* form controls sit heavier than cards */
    --line-soft:   #eef1f6;   /* dividers inside a card */
    --line-dark:   rgba(255, 255, 255, .10);

    /* ink -------------------------------------------------------------- */
    --ink:         #0b1220;
    --ink-2:       #1e293b;
    --slate:       #334155;
    --muted:       #475569;
    --dim:         #64748b;
    --faint:       #94a3b8;
    --on-dark:     #dce3ec;

    /* status ----------------------------------------------------------- */
    --green:       #12a33a;
    --green-solid: #16a34a;
    --green-ink:   #16964a;
    --green-bg:    #e3f5e9;
    --green-line:  #bce5cb;
    --amber:       #fdb20b;
    --amber-bg:    #fff8e6;
    --violet:      #5b34c6;
    --violet-2:    #6b44dc;
    --red:         #dc2626;
    --red-bg:      #fef2f2;
    --red-line:    #fecaca;

    /* geometry --------------------------------------------------------- */
    --r-card:      14px;
    --r-ctl:       12px;
    --r-btn:       10px;
    --r-sm:        8px;
    --r-pill:      999px;
    --radius:      14px;   /* legacy aliases */
    --radius-sm:   10px;

    --shadow-card: 0 1px 2px rgba(16, 24, 40, .04), 0 6px 16px -6px rgba(16, 24, 40, .07);
    --shadow-lift: 0 2px 4px rgba(16, 24, 40, .05), 0 12px 26px -10px rgba(16, 24, 40, .13);
    --shadow-pop:  0 2px 8px rgba(15, 23, 42, .14);
    --shadow:      var(--shadow-card);
    --shadow-md:   var(--shadow-lift);

    --ring:        0 0 0 3px rgba(13, 92, 226, .22);

    --maxw:        1360px;
    --gutter:      16px;
    --nav-h:       60px;

    --font: -apple-system, BlinkMacSystemFont, "Segoe UI Variable Display", "Segoe UI",
            Inter, Roboto, "Helvetica Neue", Arial, sans-serif;
}

@media (min-width: 640px) {
    :root { --gutter: 24px; --nav-h: 72px; }
}
@media (min-width: 1024px) {
    :root { --gutter: 32px; --nav-h: 76px; }
}
@media (min-width: 1240px) {
    :root { --gutter: 40px; }
}

/* -------------------------------------------------------------- base/reset */

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }

body {
    background: var(--bg);
    color: var(--ink);
    font: 400 16px/1.55 var(--font);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

img, svg, video, canvas { max-width: 100%; }
img { border-style: none; }

a { color: var(--blue-ink); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible {
    outline: 2px solid var(--blue);
    outline-offset: 2px;
    border-radius: 4px;
}

h1, h2, h3, h4, h5 {
    margin: 0 0 .5em;
    color: var(--ink);
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: -.02em;
}
h1 { font-size: 1.75rem; }
h2 { font-size: 1.25rem; }
h3 { font-size: 1.06rem; font-weight: 700; }
h4 { font-size: .95rem; font-weight: 700; letter-spacing: -.01em; }
p  { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }
hr { border: 0; border-top: 1px solid var(--line-soft); margin: 24px 0; }

b, strong { font-weight: 700; }
small { font-size: .875em; }

table { border-collapse: collapse; width: 100%; }

@media (min-width: 640px) {
    h1 { font-size: 2rem; }
    h2 { font-size: 1.35rem; }
}
@media (min-width: 1024px) {
    h1 { font-size: 2.25rem; }
    h2 { font-size: 1.45rem; }
    h3 { font-size: 1.12rem; }
}

/* ------------------------------------------------------------- containers */

.wrap {
    width: 100%;
    max-width: var(--maxw);
    margin: 0 auto;
    padding: 0 var(--gutter);
}

/* Marketing pages inset their copy a further step in from the full container.
   Getting these two levels right is most of why the mockup reads "designed". */
.wrap-text { padding: 0; }
@media (min-width: 1024px) { .wrap-text { padding: 0 40px; } }
@media (min-width: 1240px) { .wrap-text { padding: 0 70px; } }

.narrow { width: 100%; max-width: 640px; margin: 0 auto; padding: 0 var(--gutter); }
.narrow-md { width: 100%; max-width: 860px; margin: 0 auto; padding: 0 var(--gutter); }

.page { padding: 24px 0 48px; }
@media (min-width: 640px)  { .page { padding: 32px 0 64px; } }
@media (min-width: 1024px) { .page { padding: 40px 0 80px; } }

/* ------------------------------------------------------------------ icons */
/* icon() emits presentation attributes (fill/stroke) on the <svg> itself, so
   CSS must NEVER set fill or stroke on .ico — colour comes from `color`
   through currentColor, which serves the outline and the solid set alike. */

.ico {
    width: 1.15em;
    height: 1.15em;
    flex: 0 0 auto;
    vertical-align: -.16em;
}
.ico-12 { width: 12px; height: 12px; }
.ico-14 { width: 14px; height: 14px; }
.ico-16 { width: 16px; height: 16px; }
.ico-18 { width: 18px; height: 18px; }
.ico-20 { width: 20px; height: 20px; }
.ico-22 { width: 22px; height: 22px; }
.ico-24 { width: 24px; height: 24px; }
.ico-28 { width: 28px; height: 28px; }
.ico-32 { width: 32px; height: 32px; }
.ico-blue   { color: var(--blue); }
.ico-muted  { color: var(--muted); }
.ico-dim    { color: var(--faint); }
.ico-green  { color: var(--green); }
.ico-amber  { color: var(--amber); }
.ico-white  { color: #fff; }

/* ---------------------------------------------------------------- top nav */

.topnav {
    position: sticky;
    top: 0;
    z-index: 60;
    background: var(--navy);
    color: #fff;
}

/* Focusable-but-invisible checkbox drives the mobile drawer with no JS and no
   inline handlers, which keeps the strict CSP intact. */
.nav-check,
.search-check,
.menu-check {
    position: absolute;
    width: 1px; height: 1px;
    margin: 0;
    opacity: 0;
    pointer-events: none;
}

.navbar,
.topnav > .wrap {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: var(--nav-h);
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    margin-right: auto;
    color: #fff;
    font-size: 1.2rem;
    font-weight: 800;
    letter-spacing: -.025em;
    white-space: nowrap;
}
.brand:hover { text-decoration: none; color: #fff; }
.brand .ico { width: 26px; height: 26px; color: var(--blue-bright); vertical-align: 0; }

@media (min-width: 640px)  { .brand { font-size: 1.32rem; } .brand .ico { width: 29px; height: 29px; } }
@media (min-width: 1024px) { .brand { font-size: 1.45rem; margin-right: 40px; } .brand .ico { width: 32px; height: 32px; } }

/* Marketing header (logged out) — mockup (1) is white with a dark wordmark,
   grey labels, a blue text "Log In" and a blue filled "Sign Up". Every
   authenticated screen keeps the navy bar. */
.topnav-light { background: #fff; color: var(--ink); border-bottom: 1px solid var(--line); }
.topnav-light .brand,
.topnav-light .brand:hover { color: var(--ink); }
/* Drawer-only. Specificity (0,2,0) outranks the desktop reset on .navlinks
   (0,1,0) no matter the source order, so without this media query the white
   panel and its shadow leak onto the desktop header. */
@media (max-width: 1023px) {
    .topnav-light .navlinks {
        background: #fff;
        border-top-color: var(--line);
        box-shadow: 0 18px 30px -18px rgba(15, 23, 42, .35);
    }
}
.topnav-light .navlinks a { color: var(--slate); border-bottom-color: var(--line-soft); }
.topnav-light .navlinks a:hover,
.topnav-light .navlinks a.active { color: var(--ink); }
.topnav-light .navright > a:not(.btn):not(.avatar-nav) { color: var(--blue); }
.topnav-light .navright > a:not(.btn):not(.avatar-nav):hover { color: var(--blue-hover); }
.topnav-light .nav-icon,
.topnav-light .nav-burger { color: var(--slate); }
.topnav-light .nav-icon:hover,
.topnav-light .nav-burger:hover { background: var(--bg-tint); color: var(--ink); }
.topnav-light .navsearch input {
    background: var(--bg-tint);
    border-color: var(--line);
    color: var(--ink);
}
.topnav-light .navsearch input::placeholder { color: var(--muted); }
.topnav-light .navsearch input:focus { background: #fff; border-color: var(--blue); }
.topnav-light .navsearch > .ico { color: var(--muted); }
.topnav-light .nav-check:focus-visible ~ .wrap .nav-burger,
.topnav-light .search-check:focus-visible ~ .wrap .nav-search-btn { outline-color: var(--blue); }
/* Follows the panel breakpoint below, not the drawer's: the search opens as a
   row under the bar all the way to 1199px now. */
@media (max-width: 1199px) {
    .topnav-light .search-check:checked ~ .wrap .navsearch {
        background: #fff;
        border-top-color: var(--line);
        box-shadow: 0 18px 30px -18px rgba(15, 23, 42, .35);
    }
}

/* hamburger ------------------------------------------------------------- */
.nav-burger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px; height: 42px;
    border-radius: var(--r-btn);
    color: #fff;
    cursor: pointer;
    order: 9;
}
.nav-burger:hover { background: rgba(255, 255, 255, .10); }
.nav-burger .ico { width: 22px; height: 22px; }
.nav-check:focus-visible ~ .navbar .nav-burger,
.nav-check:focus-visible ~ .wrap .nav-burger,
.search-check:focus-visible ~ .wrap .nav-search-btn,
.menu-check:focus-visible ~ .wrap .avatar-btn { outline: 2px solid #fff; outline-offset: 2px; }

/* links ----------------------------------------------------------------- */
/* `left/right: 0`, NOT `calc(var(--gutter) * -1)`. An absolutely positioned
   box resolves its offsets against the containing block's PADDING box, and
   `.wrap` is border-box with `padding: 0 var(--gutter)` and no border — so its
   padding box already spans the whole bar. The negative offsets did not cancel
   the gutter, they pushed the panel a full gutter PAST each viewport edge, and
   with no `overflow-x: hidden` anywhere the document gained real horizontal
   scroll whenever the drawer was open. (`.tabs` further down uses the same
   numbers correctly — it is a normal-flow element, so its containing block
   really is `.wrap`'s content box.) */
.navlinks {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    padding: 6px var(--gutter) 14px;
    background: var(--navy);
    border-top: 1px solid rgba(255, 255, 255, .08);
    box-shadow: 0 18px 30px -18px rgba(0, 0, 0, .8);
}
.nav-check:checked ~ .navbar .navlinks,
.nav-check:checked ~ .wrap .navlinks { display: flex; }

/* The drawer and the search reveal are independent checkboxes and nothing stops
   both being checked at once. Both panels are absolutely positioned at
   `top: 100%` of the same `.wrap`, and the search panel carries `z-index: 65`
   against the drawer's `auto` — so it painted over the drawer's first two rows
   and swallowed their taps. Search wins: opening it closes the drawer, and
   closing it again brings the drawer straight back if it was open.
   This ties with the rule above at (0,4,0), so it MUST stay below it, and it is
   scoped to the drawer's own range — from 1024px `.navlinks` is the static
   desktop row and hiding it would delete the primary nav. */
@media (max-width: 1023px) {
    .search-check:checked ~ .wrap .navlinks { display: none; }
}

.navlinks a {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 2px;
    color: var(--on-dark);
    font-size: 1rem;
    font-weight: 500;
    border-bottom: 1px solid rgba(255, 255, 255, .06);
}
/* :last-of-type, not :last-child — in the signed-in drawer the last child of
   .navlinks is the sign-out <form>, so :last-child matches no anchor and the
   final link keeps a divider that doubles against .navdrawer-signout. */
.navlinks a:last-of-type { border-bottom: 0; }
.navlinks a:hover { color: #fff; text-decoration: none; }
.navlinks a.active { color: #fff; font-weight: 700; }

@media (min-width: 1024px) {
    .nav-burger { display: none; }
    .navlinks {
        display: flex;
        position: static;
        flex-direction: row;
        align-items: center;
        gap: 34px;
        padding: 0;
        margin-right: 24px;
        background: none;
        border-top: 0;
        box-shadow: none;
    }
    .navlinks a {
        padding: 0;
        border-bottom: 0;
        font-size: 1.02rem;
        line-height: var(--nav-h);
    }
    /* the active underline hugs the label exactly, it is not a padded tab */
    .navlinks a.active::after {
        content: "";
        position: absolute;
        left: 0; right: 0;
        bottom: 16px;
        height: 3px;
        border-radius: 2px;
        background: #3b82f6;
    }
}
/* 1360px, not 1200px: `--maxw` is 1360, so this is the first width at which
   `.wrap` stops growing and the three tracks stop competing. Below it the
   tightened band further down wins on source order. */
@media (min-width: 1360px) { .navlinks { gap: 44px; } }

/* right cluster --------------------------------------------------------- */
.navright {
    display: flex;
    align-items: center;
    gap: 10px;
}
@media (min-width: 1024px) { .navright { gap: 18px; } }

.navright > a:not(.btn):not(.avatar-nav) {
    color: var(--on-dark);
    font-weight: 600;
    font-size: .95rem;
}
.navright > a:not(.btn):not(.avatar-nav):hover { color: #fff; text-decoration: none; }

.nav-icon {
    display: inline-grid;
    place-items: center;
    width: 40px; height: 40px;
    border: 0;
    border-radius: var(--r-btn);
    background: none;
    color: #fff;
    cursor: pointer;
}
.nav-icon:hover { background: rgba(255, 255, 255, .10); text-decoration: none; color: #fff; }
.nav-icon .ico { width: 21px; height: 21px; }
.nav-icon-hide-sm { display: none; }
@media (min-width: 640px) { .nav-icon-hide-sm { display: inline-grid; } }

.avatar-nav {
    display: grid;
    place-items: center;
    width: 36px; height: 36px;
    flex: 0 0 auto;
    border-radius: 50%;
    border: 2px solid #fff;
    background: var(--blue);
    color: #fff;
    font-size: .9rem;
    font-weight: 800;
    object-fit: cover;
    overflow: hidden;
}
.avatar-nav:hover { text-decoration: none; color: #fff; }
@media (min-width: 1024px) { .avatar-nav { width: 44px; height: 44px; font-size: 1rem; } }

.nav-caret { color: rgba(255, 255, 255, .8); display: none; }
@media (min-width: 640px) { .nav-caret { display: inline-flex; } }
/* icon() puts the class ON the <svg>, so this sizes the caret itself. */
.nav-caret { width: 16px; height: 16px; }

/* Avatar + caret is one control: it opens the account menu, which is where
   Sign out lives. No mockup shows Sign out standing in the bar. */
.avatar-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px;
    border-radius: var(--r-pill);
    cursor: pointer;
}
.avatar-btn:hover { background: rgba(255, 255, 255, .10); }

.navmenu {
    display: none;
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    z-index: 70;
    min-width: 216px;
    padding: 6px;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--r-ctl);
    box-shadow: var(--shadow-pop), var(--shadow-lift);
}
.menu-check:checked ~ .wrap .navmenu { display: block; }
.navmenu a,
.navmenu button {
    display: flex;
    align-items: center;
    gap: 11px;
    width: 100%;
    padding: 10px 12px;
    border: 0;
    border-radius: var(--r-btn);
    background: none;
    color: var(--ink-2);
    font: inherit;
    font-size: .95rem;
    font-weight: 500;
    text-align: left;
    cursor: pointer;
}
.navmenu a:hover,
.navmenu button:hover { background: var(--bg-tint); color: var(--ink); text-decoration: none; }
.navmenu .ico { width: 18px; height: 18px; color: var(--muted); }
.navmenu .rule { height: 1px; margin: 6px 4px; background: var(--line-soft); }
.navmenu .head { padding: 8px 12px 4px; color: var(--dim); font-size: .78rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }

/* nav search ------------------------------------------------------------ */
/* The mockups show a magnifier in the bar, not a standing 220px pill: the field
   is revealed by the .nav-search-btn label. Up to 1199px it opens as a
   full-bleed row under the bar; only from 1200px is there room for the inline
   pill in the right cluster. 1024-1199 signed-in used to render it inline and
   left roughly 90px of field — about three characters of typed text and no
   visible placeholder at all — so that band is a panel band now too.

   SPECIFICITY, load-bearing: every rule that sizes or paints the field is
   written `.topnav .navsearch input` (0,2,1). The generic form-control block
   further down this sheet (`input[type=text], … input[type=search], select,
   textarea`) is (0,1,1) AND comes later, so a bare `.navsearch input` ties and
   LOSES every shared property: the field silently took min-height 52px, 16px
   of left padding (which put the magnifier on top of the placeholder), the
   12px control radius instead of the pill, and a solid white background on the
   navy bar. Never drop the `.topnav` prefix from these.

   ORDER, also load-bearing: the responsive overrides sit AFTER the base rule.
   They tie with it at (0,2,1) and a media query contributes no specificity, so
   placed above it they would never apply. */
.navsearch { position: relative; display: none; }
.search-check:checked ~ .wrap .navsearch { display: block; }

/* Geometry — both header states. Colour is on the two modifiers below. */
.topnav .navsearch input {
    width: 220px;
    min-height: 0;
    padding: 9px 14px 9px 38px;
    border-radius: var(--r-pill);
    font: inherit;
    font-size: .92rem;
    transition: background .18s ease, border-color .18s ease;
}
.topnav .navsearch input:focus { outline: none; }

/* Navy bar only. `:not(.topnav-light)` rather than a plain `.topnav` prefix so
   this can never race `.topnav-light .navsearch input` above, which is the
   same (0,2,1) and comes earlier in the sheet: the two selectors are mutually
   exclusive, so source order stops mattering. */
.topnav:not(.topnav-light) .navsearch input {
    background: rgba(255, 255, 255, .09);
    border: 1px solid rgba(255, 255, 255, .16);
    color: #fff;
}
.topnav:not(.topnav-light) .navsearch input::placeholder { color: #93a4b8; }
.topnav:not(.topnav-light) .navsearch input:focus {
    background: rgba(255, 255, 255, .16);
    border-color: rgba(255, 255, 255, .45);
}

/* Left at (0,2,0) on purpose: `.topnav-light .navsearch > .ico` above is
   (0,3,0) and must keep winning on the white header. */
.navsearch > .ico {
    position: absolute;
    left: 13px; top: 50%;
    width: 16px; height: 16px;
    transform: translateY(-50%);
    color: #93a4b8;
}

/* Below 1200px the field is a full-bleed row under the bar. `left/right: 0`
   and NOT `calc(var(--gutter) * -1)` — see the identical note on `.navlinks`:
   the offsets resolve against `.wrap`'s padding box, which already spans the
   bar, so the negative values pushed the panel a gutter past each viewport
   edge and gave the page horizontal scroll while it was open. */
@media (max-width: 1199px) {
    .search-check:checked ~ .wrap .navsearch {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        z-index: 65;
        padding: 12px var(--gutter) 16px;
        background: var(--navy);
        border-top: 1px solid rgba(255, 255, 255, .08);
        box-shadow: 0 18px 30px -18px rgba(0, 0, 0, .8);
    }
    .topnav .navsearch input { width: 100%; }
    /* The panel's own gutter padding sets the field's left edge, so the
       magnifier has to travel with it — otherwise it sits in the panel's
       padding, clear of the input it belongs to. */
    .navsearch > .ico { left: calc(var(--gutter) + 13px); }
}

.search-results {
    position: absolute;
    top: calc(100% + 8px);
    left: 0; right: 0;
    min-width: 320px;
    z-index: 70;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--r-ctl);
    box-shadow: var(--shadow-lift);
    overflow: hidden;
}
.search-results a {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 14px;
    color: var(--ink);
    font-size: .93rem;
    border-bottom: 1px solid var(--line-soft);
}
.search-results a:last-child { border-bottom: 0; }
.search-results a:hover,
.search-results a.sel { background: var(--blue-soft); text-decoration: none; }
.search-results .kind {
    margin-left: auto;
    color: var(--faint);
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    white-space: nowrap;
}
.search-results .empty-row { padding: 13px 14px; color: var(--muted); font-size: .9rem; }
@media (min-width: 1024px) { .search-results { left: auto; right: 0; } }

/* ------------------------------------------------ header: three-zone grid */
/* The brief: brand left, primary nav genuinely centred, controls right.
   A flex row cannot centre the middle zone — with two growing spacers the nav
   lands in the middle of the LEFTOVER space, so it slides every time the
   brand or the right cluster changes width. A three-track grid can: the two
   1fr tracks are equal by definition and the single symmetric column-gap
   cancels out of the arithmetic, so the middle track midpoint IS the
   container midpoint no matter how wide the outer clusters are.

   SPECIFICITY: written `.topnav > .wrap.nav-grid` = (0,3,0). A bare
   `.nav-grid` is (0,1,0) and loses to the existing `.topnav > .wrap` (0,2,0)
   whatever the source order — the grid would silently never apply. This is
   the same trap that once leaked the white `.topnav-light .navlinks` drawer
   panel onto the desktop header.

   BELOW 1024px `.nav-grid` defines NOTHING. `.wrap` keeps its flex row, the
   brand keeps `margin-right: auto`, the burger keeps `order: 9`, and — the
   load-bearing part — `.wrap` keeps `position: relative`, which is what the
   drawer panel, the search panel and the search-results dropdown are
   positioned against. The `.nav-check:checked ~ .wrap .navlinks` and
   `.search-check:checked ~ .wrap .navsearch` sibling hops are untouched. */

/* The revealed search field is the single biggest driver of the right
   cluster width. Let it shrink rather than push the header past the viewport:
   `.navright { min-width: 0 }` lets the third track fall below its content,
   `.navsearch { min-width: 0 }` lets the form shrink inside the flex cluster,
   and `max-width: 100%` makes the fixed-width input follow. Nothing else in
   the cluster shrinks (icons, avatar and the sign-out form are all
   `flex: 0 0 auto`), so the field is the only thing that gives. */
.navsearch { min-width: 0; }
.navsearch input { max-width: 100%; }

@media (min-width: 1024px) {
    .topnav > .wrap.nav-grid {
        display: grid;
        grid-template-columns: 1fr auto 1fr;
        column-gap: 24px;
        /* position / align-items / min-height are inherited from
           `.topnav > .wrap` and are deliberately NOT re-declared here. */
    }

    /* Track 1. The 40px desktop `margin-right` would shove the whole left
       track content; `margin-right: auto` is meaningless in grid.
       `justify-self: start` stops the anchor hit area spanning the full 1fr
       track. Deliberately NO `min-width: 0`: the wordmark is the one thing
       that must never be allowed to shrink under the centred nav, so track 1
       keeps a real min-content floor. */
    .nav-grid > .brand { margin-right: 0; justify-self: start; }

    /* Track 2. The desktop `.navlinks { margin-right: 24px }` would sit the
       centred zone 24px left of true centre. `nowrap` keeps the four
       signed-in labels on one line so the auto track has a stable width.
       This rule touches layout only — no background, border or shadow — so
       the `max-width: 1023px` scoped `.topnav-light .navlinks` (0,2,0)
       drawer rule is not in play and cannot leak onto the desktop bar. */
    .nav-grid > .navlinks { margin-right: 0; justify-self: center; white-space: nowrap; }

    /* Track 3. Without `justify-self: end` the cluster stretches and its
       contents sit at the track LEFT edge, which reads as a gap between the
       nav and the controls. `min-width: 0` is the overflow guard described
       above: plain `1fr` (not `minmax(0,1fr)`) keeps the two outer tracks
       equal while there is room, and when there is not the right track
       narrows and the nav drifts a few px — graceful drift, never overlap,
       and never a horizontally scrolling page. */
    .nav-grid > .navright { justify-self: end; min-width: 0; }
}

/* Everything from 1024px to 1359px is a competing-tracks state: `.wrap` is
   still growing with the viewport, so the centred nav, the wordmark and the
   right cluster are all bidding for the same row. Tighten the three gaps
   across that whole range — the old cut at 1199px reverted them at exactly the
   width where the nav gap widened by 48px, which took ~91px out of the right
   cluster in a single 1px step and was most of why the search field collapsed.
   From 1360px `.wrap` is pinned at `--maxw` and there is slack for the wide
   gaps again.

   The old `.navsearch input { width: 190px }` cap in here is gone: below
   1200px the field is a panel and takes 100%, and from 1200px the flex shrink
   already described on `.navsearch` sizes it to whatever track 3 can give
   (~180px at 1200, ~212px at 1360+) — a second fixed cap only ever made it
   smaller. The focus width jump went with it: it could never fit, so it just
   shoved the centred nav sideways on every click. */
@media (min-width: 1024px) and (max-width: 1359px) {
    .topnav > .wrap.nav-grid { column-gap: 20px; }
    .navlinks { gap: 28px; }
    .navright { gap: 14px; }
}

/* avatar link ----------------------------------------------------------- */
/* Replaces the old `.avatar-btn` label: the avatar is now a plain link to the
   member profile. Sizing comes from `.avatar-nav` (36px, 44px at 1024px), so
   this wrapper only supplies the hit area and the hover wash. */
.navavatar {
    display: inline-flex;
    align-items: center;
    padding: 2px;
    border-radius: 50%;
    flex: 0 0 auto;
}
.navavatar:hover { background: rgba(255, 255, 255, .10); text-decoration: none; }
.topnav-light .navavatar:hover { background: var(--bg-tint); }
/* The global `:focus-visible { outline: 2px solid var(--blue) }` is close to
   invisible against --navy #001229, so the navy bar needs a white ring. */
.topnav .navavatar:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.topnav-light .navavatar:focus-visible { outline-color: var(--blue); }

/* sign out in the bar --------------------------------------------------- */
/* Hidden below 640px by the existing `.hide-sm` utility — at 360px the bar
   already carries brand + search + avatar + burger and a fifth control would
   overflow. The drawer copy below stands in at that width. No competing
   display rule is written at that breakpoint. */
@media (min-width: 640px) {
    .nav-signout-form { display: flex; align-items: center; flex: 0 0 auto; margin: 0; padding: 0; }
}

/* A quiet ghost control, never a filled button: the filled blue treatment is
   reserved for Sign Up. */
.nav-signout {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: var(--r-btn);
    background: none;
    color: var(--on-dark);
    font: inherit;
    font-size: .95rem;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
}
.nav-signout .ico { width: 18px; height: 18px; }
.nav-signout:hover { background: rgba(255, 255, 255, .10); color: #fff; }
.topnav-light .nav-signout { color: var(--slate); }
.topnav-light .nav-signout:hover { background: var(--bg-tint); color: var(--ink); }
.topnav .nav-signout:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.topnav-light .nav-signout:focus-visible { outline-color: var(--blue); }

/* The label is visually hidden — never `display: none` — so the icon-only
   button keeps its accessible name, and `title="Sign out"` in layout.php gives
   sighted users the tooltip. It stays hidden at EVERY width now. The old
   reveal fired at 1200px, the same breakpoint that widened the nav gap, and
   the ~63px of button it added landed on the only shrinkable thing in the
   right cluster: the search field. There is no width at which the wordmark,
   a centred four-item nav, a usable search field, the avatar and a labelled
   sign-out all fit — `.wrap` is capped at 1360px, so the widest bar is the
   1360px bar. An icon-only sign-out beside the avatar is the ordinary reading
   of that cluster; the drawer keeps a fully labelled "Sign out" row below
   640px where the bar button is hidden altogether. */
.nav-signout-label {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* sign out inside the drawer -------------------------------------------- */
/* Visibility is owned ENTIRELY by the existing `.only-sm` utility
   (`display: revert` at base, `display: none !important` from 640px). No
   display property is declared here on purpose: at (0,1,0) it would tie with
   `.only-sm` and the result would become source-order dependent. */
.navdrawer-form { margin: 0; padding: 0; }

/* Must be indistinguishable from a `.navlinks a` row so the open drawer reads
   as one list. It takes a border-TOP, not the links border-bottom, because
   `.navlinks a:last-child { border-bottom: 0 }` has already stripped the
   divider immediately above it. */
.navdrawer-signout {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 12px 2px;
    border: 0;
    border-top: 1px solid rgba(255, 255, 255, .06);
    border-radius: 0;
    background: none;
    color: var(--on-dark);
    font: inherit;
    font-size: 1rem;
    font-weight: 500;
    text-align: left;
    cursor: pointer;
}
.navdrawer-signout .ico { width: 18px; height: 18px; }
.navdrawer-signout:hover { color: #fff; }
.topnav .navdrawer-signout:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* `.navmenu`, `.menu-check`, `.avatar-btn` and `.nav-caret` above are now
   unreferenced — layout.php dropped the account dropdown in favour of the
   avatar link plus a standing sign-out control, and Settings moved to the
   footer. The rules are left in place deliberately: they are inert, they cost
   only bytes, and nothing else in private/ or html/assets/js/ names them. */

/* ---------------------------------------------------------------- buttons */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    padding: 12px 22px;
    min-height: 46px;
    background: var(--blue);
    color: #fff;
    border: 1px solid transparent;
    border-radius: var(--r-btn);
    font: inherit;
    font-size: .97rem;
    font-weight: 700;
    line-height: 1.2;
    text-align: center;
    white-space: nowrap;
    cursor: pointer;
    transition: background .15s ease, border-color .15s ease, box-shadow .15s ease, color .15s ease;
}
.btn:hover { background: var(--blue-hover); color: #fff; text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; transform: none; }
.btn .ico { width: 18px; height: 18px; vertical-align: 0; }

.btn-ghost {
    background: #fff;
    color: var(--ink);
    border-color: var(--line-strong);
}
.btn-ghost:hover { background: var(--bg-tint); color: var(--ink); border-color: #c7cede; }

.btn-quiet { background: none; color: var(--muted); border-color: transparent; }
.btn-quiet:hover { background: var(--line-soft); color: var(--ink); }

.btn-danger { background: #fff; color: var(--red); border-color: var(--red-line); }
.btn-danger:hover { background: var(--red-bg); color: var(--red); border-color: var(--red); }

.btn-lg { min-height: 56px; padding: 15px 30px; font-size: 1.05rem; border-radius: var(--r-ctl); }
.btn-sm { min-height: 38px; padding: 8px 16px; font-size: .88rem; gap: 7px; }
.btn-sm .ico { width: 15px; height: 15px; }
.btn-block { width: 100%; }
.btn-icon { width: 48px; min-height: 48px; padding: 0; }
.btn-icon .ico { width: 20px; height: 20px; }

/* Three actions have to fit a 640px .narrow column, which at the widest
   gutter leaves 560px of content. At the default 22px button padding the row
   measures about 573px, so flex-wrap did as it was told and dropped the third
   button to its own line. Trimming the padding and the gap here brings it to
   roughly 533px — comfortably inside, with room for a longer label later. */
.cta-row { display: flex; flex-wrap: wrap; gap: 10px; }
.cta-row > .btn { flex: 1 1 100%; }
@media (min-width: 480px) {
    .cta-row > .btn { flex: 0 0 auto; padding-inline: 16px; white-space: nowrap; }
}

/* text link that reads as an action, with a trailing arrow */
.actionlink {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--blue-ink);
    font-size: .92rem;
    font-weight: 600;
    white-space: nowrap;
}
.actionlink:hover { text-decoration: none; color: var(--blue-hover); }
.actionlink .ico { width: 16px; height: 16px; transition: transform .15s ease; }
.actionlink:hover .ico { transform: translateX(2px); }

.backlink {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 14px;
    color: var(--blue-ink);
    font-size: .95rem;
    font-weight: 600;
}
.backlink:hover { text-decoration: none; }
.backlink .ico { width: 17px; height: 17px; }

/* ------------------------------------------------------------------ cards */

.card {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--r-card);
    box-shadow: var(--shadow-card);
    padding: 18px;
}
@media (min-width: 640px) { .card { padding: 24px; } }

/* Cards sitting side by side in a grid lay their content out as a column and
   let the description absorb the leftover height, so headings start at the
   same y and action links finish at the same y across the row. */
.cols-3 > .card,
.cols-4 > .card,
.cols-2 > .card {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}
.cols-3 > .card > p,
.cols-4 > .card > p,
.cols-2 > .card > p { flex: 1 0 auto; }
.cols-3 > .card > .actionlink,
.cols-4 > .card > .actionlink,
.cols-2 > .card > .actionlink { margin-top: auto; }
/* A flush card manages its own internal padding and must not be columnised. */
.cols-3 > .card-flush,
.cols-4 > .card-flush,
.cols-2 > .card-flush { display: block; }
.card + .card { margin-top: 20px; }

/* `.card + .card` above is right for cards stacked in NORMAL FLOW and wrong
   for cards that are adjacent siblings inside a GRID. A grid item's margin is
   applied inside its own cell, and the container's `gap` has already supplied
   the spacing — so in .cols-3 the second and third cards each pick up 20px of
   top margin and sit 20px lower in their own cells than the first. That is
   exactly why "The Map", "Aviation Score" and "Flight Passport" looked
   untidy, and the same latent bug affects every grid below.

   Neutralise it at the container, never with compensating margins elsewhere,
   and never by deleting the base rule — stacked cards in normal flow still
   need it. Each selector here is (0,3,0) and beats the (0,2,0) base rule at
   every breakpoint. When one of these grids collapses to a single column the
   cells are still separate cells and `gap` still spaces them, so 0 stays
   correct there too (it also removes the doubled 20px+20px these grids were
   producing in their one-column state). */
.grid        > .card + .card,
.grid-2      > .card + .card,
.grid-3      > .card + .card,
.stack       > .card + .card,
.stack-sm    > .card + .card,
.cols-2      > .card + .card,
.cols-3      > .card + .card,
.cols-4      > .card + .card,
.cols-wide   > .card + .card,
.cols-main   > .card + .card,
.split       > .card + .card,
.split-wide  > .card + .card,
.split-media > .card + .card,
.fleet-grid  > .card + .card,
.badge-grid  > .card + .card,
.quote-grid  > .card + .card,
.row         > .card + .card,
.row-3       > .card + .card,
.pillars     > .card + .card { margin-top: 0; }

.card-hover { transition: box-shadow .18s ease, border-color .18s ease, transform .18s ease; }
.card-hover:hover { box-shadow: var(--shadow-lift); border-color: #dbe2ec; }

/* Flush card: the header keeps its padding, the body runs to the edges (tables,
   ranked lists, maps). */
.card-flush { padding: 0; overflow: hidden; }

/* Card header: title left, one action link right. Present on every content
   card in the mockups — this is the detail the flat build was missing. */
.card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    margin-bottom: 16px;
}
.card-head h2, .card-head h3, .card-head .card-h { margin: 0; font-size: 1.12rem; font-weight: 700; letter-spacing: -.015em; }
/* A padded card gets the same hairline under its header as a flush one; the
   divider is what makes a card read as designed rather than as a box of text.
   Declared before the flush rule so the flush rule (same specificity) wins. */
.card > .card-head {
    padding-bottom: 15px;
    border-bottom: 1px solid var(--line-soft);
}
.card-flush > .card-head {
    margin-bottom: 0;
    padding: 16px 18px;
    border-bottom: 1px solid var(--line-soft);
}
@media (min-width: 640px) { .card-flush > .card-head { padding: 18px 24px; } }
.card-flush > .card-head.is-seamless { border-bottom: 0; }
.card-body { padding: 18px; }
@media (min-width: 640px) { .card-body { padding: 24px; } }
.card-foot {
    padding: 14px 18px;
    border-top: 1px solid var(--line-soft);
    background: var(--bg-tint);
    font-size: .9rem;
    color: var(--muted);
}

/* legacy alias kept working */

/* --------------------------------------------------------------- page head */

.page-head {
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin-bottom: 24px;
}
.page-head h1 { margin: 0; }
.page-head .sub { margin: 8px 0 0; color: var(--muted); font-size: 1rem; max-width: 62ch; }
.page-head .acts { display: flex; flex-wrap: wrap; gap: 10px; }
.page-head .acts > .btn { flex: 1 1 auto; }
@media (min-width: 768px) {
    .page-head { flex-direction: row; align-items: center; justify-content: space-between; gap: 24px; margin-bottom: 32px; }
    .page-head .acts > .btn { flex: 0 0 auto; }
}
@media (min-width: 1024px) { .page-head { margin-bottom: 36px; } }

/* ----------------------------------------------------------------- grids */

.grid { display: grid; gap: 20px; }
.cols-2 { display: grid; gap: 20px; grid-template-columns: 1fr; }
.cols-3 { display: grid; gap: 20px; grid-template-columns: 1fr; }
.cols-4 { display: grid; gap: 16px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 640px)  { .cols-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* .cols-2 and .split carry the same pair of ranked lists, so they go two-up at
   the same width. At 640px each column is ~325px, which is not enough for a
   "Departure City / San Francisco (SFO)" row. */
@media (min-width: 900px)  { .cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } .cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 20px; } }

/* Recent Flights (wide) beside Flight Map (narrow) on the dashboard. */
.cols-wide { display: grid; gap: 20px; grid-template-columns: 1fr; }
@media (min-width: 1100px) { .cols-wide { grid-template-columns: minmax(0, 1.31fr) minmax(0, 1fr); gap: 24px; } }

/* Content column + fixed right rail (Add Flight, Flight Details). */
/* No align-items:start here: the <aside> has to stretch to the row height, or
   .sticky-side (its only child) has zero travel and never actually sticks. */
.cols-main { display: grid; gap: 20px; grid-template-columns: 1fr; }
.cols-main > * { min-width: 0; }
@media (min-width: 1100px) { .cols-main { grid-template-columns: minmax(0, 1fr) 368px; gap: 28px; } }
@media (min-width: 1240px) { .cols-main { grid-template-columns: minmax(0, 1fr) 390px; gap: 30px; } }

/* Order helpers so the single-column stack reads in a sensible order:
   the rail's summary should not be buried under the map and the stats. */
.rail-first { order: -1; }
@media (min-width: 1100px) { .rail-first { order: 0; } }

.stack { display: grid; gap: 20px; align-content: start; }
.stack-sm { display: grid; gap: 12px; align-content: start; }

/* legacy aliases */
.grid-2 { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.grid-3 { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
.split { display: grid; gap: 20px; grid-template-columns: 1fr; }
.split-wide { display: grid; gap: 20px; grid-template-columns: 1fr; align-items: start; }
@media (min-width: 900px) {
    .split { grid-template-columns: 1fr 1fr; }
    .split-wide { grid-template-columns: 1.55fr 1fr; }
}

.sticky-side { position: static; }
@media (min-width: 1100px) {
    .sticky-side {
        position: sticky;
        top: calc(var(--nav-h) + 20px);
        /* A rail taller than the viewport would otherwise pin its top and put
           its lower cards permanently out of reach. */
        max-height: calc(100vh - var(--nav-h) - 40px);
        overflow-y: auto;
        overscroll-behavior: contain;
    }
}

/* ------------------------------------------------------------------ forms */

.field { margin-bottom: 18px; }
.field:last-child { margin-bottom: 0; }
.field > label,
.field .lbl {
    display: block;
    margin-bottom: 8px;
    color: var(--muted);
    font-size: .92rem;
    font-weight: 500;
}
.field .hint { margin-top: 7px; color: var(--dim); font-size: .85rem; }
.field .err { margin-top: 7px; color: var(--red); font-size: .86rem; font-weight: 500; }
.field .opt { color: var(--faint); font-weight: 400; }

input[type=text], input[type=email], input[type=password], input[type=date],
input[type=time], input[type=number], input[type=search], input[type=tel],
input[type=url], select, textarea {
    width: 100%;
    min-height: 52px;
    padding: 13px 16px;
    background: #fff;
    color: var(--ink-2);
    border: 1px solid var(--line-strong);
    border-radius: var(--r-ctl);
    font: inherit;
    font-size: 1rem;
    transition: border-color .15s ease, box-shadow .15s ease;
}
input::placeholder, textarea::placeholder { color: var(--faint); }
input:hover, select:hover, textarea:hover { border-color: #ccd3dd; }
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--blue);
    box-shadow: var(--ring);
}
input[aria-invalid=true], select[aria-invalid=true], textarea[aria-invalid=true] { border-color: var(--red); }
input:disabled, select:disabled, textarea:disabled { background: var(--bg-tint); color: var(--dim); cursor: not-allowed; }
textarea { min-height: 110px; resize: vertical; line-height: 1.55; }

select {
    appearance: none;
    padding-right: 44px;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23334155' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 16px center;
    background-size: 18px 18px;
}

/* Field with a leading (and optionally trailing) icon. */
.input-icon { position: relative; }
.input-icon > .ico {
    position: absolute;
    top: 50%;
    left: 18px;
    width: 20px; height: 20px;
    transform: translateY(-50%);
    color: var(--faint);
    pointer-events: none;
}
.input-icon > .ico-trail {
    left: auto;
    right: 20px;
    color: var(--slate);
}
.input-icon input, .input-icon select { padding-left: 50px; }
.input-icon.has-trail input { padding-right: 52px; }

/* Big search controls on the Add Flight screen. */
.input-lg { min-height: 60px; font-size: 1.05rem; font-weight: 500; }

.searchrow { display: grid; gap: 16px; align-items: end; margin-bottom: 28px; }
.searchrow .field { margin-bottom: 0; }
@media (min-width: 640px) {
    .searchrow { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
    .searchrow > .btn { grid-column: 1 / -1; }
}
@media (min-width: 1024px) {
    .searchrow { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 340px; gap: 24px; }
    .searchrow > .btn { grid-column: auto; min-height: 60px; font-size: 1.05rem; }
}

.row   { display: grid; gap: 16px; grid-template-columns: 1fr; }
.row-3 { display: grid; gap: 16px; grid-template-columns: 1fr; }
@media (min-width: 560px) { .row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 560px) { .row-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 900px) { .row-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; } }

.check {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    font-size: .95rem;
    color: var(--slate);
    line-height: 1.5;
}
.check input { flex: 0 0 auto; width: 18px; height: 18px; min-height: 0; margin: 2px 0 0; accent-color: var(--blue); }

/* Outlined icon chips: "Add Notes / Add Photo / Who I Traveled With" */
.chip-row { display: grid; gap: 12px; grid-template-columns: 1fr; }
@media (min-width: 560px) {
    .chip-row { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); grid-auto-flow: row dense; }
    /* An open panel is a form, not a chip: it takes the whole row rather than
       being crushed into a ~200px grid track. */
    .chip-row > details[open] { grid-column: 1 / -1; }
}

.chip-btn {
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    min-height: 56px;
    padding: 14px 20px;
    background: #fff;
    color: var(--ink-2);
    border: 1px solid var(--line-strong);
    border-radius: var(--r-ctl);
    font: inherit;
    font-size: .98rem;
    font-weight: 500;
    text-align: left;
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease, color .15s ease;
}
/* <summary> keeps the native disclosure triangle unless both of these are set. */
.chip-btn { list-style: none; }
.chip-btn::-webkit-details-marker { display: none; }
.chip-btn::marker { content: ""; }
.chip-btn .ico { width: 20px; height: 20px; color: var(--slate); }
.chip-btn:hover { border-color: var(--blue); color: var(--blue); text-decoration: none; }
.chip-btn:hover .ico { color: var(--blue); }
.chip-btn[aria-expanded="true"], .chip-btn.is-on {
    border-color: var(--blue);
    background: var(--blue-soft);
    color: var(--blue-hover);
}
.chip-btn[aria-expanded="true"] .ico, .chip-btn.is-on .ico { color: var(--blue); }
@media (min-width: 1024px) { .chip-btn { min-height: 62px; } }


.reassure {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin-top: 18px;
    color: var(--muted);
    font-size: .93rem;
}
.reassure .ico { width: 17px; height: 17px; color: var(--slate); opacity: .75; }
.secure-note { display: flex; align-items: center; justify-content: center; gap: 10px; margin-top: 18px; color: var(--muted); font-size: .93rem; }
.secure-note .ico { width: 17px; height: 17px; }

/* ------------------------------------------------------------------ pills */

.pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    border-radius: var(--r-pill);
    background: var(--bg-tint);
    border: 1px solid var(--line);
    color: var(--muted);
    font-size: .8rem;
    font-weight: 600;
    white-space: nowrap;
}
.pill .ico { width: 14px; height: 14px; }
.pill-green { background: var(--green-bg); border-color: var(--green-line); color: var(--green-ink); }
.pill-blue  { background: var(--blue-soft); border-color: var(--blue-line); color: var(--blue-hover); }
.pill-amber { background: var(--amber-bg); border-color: #f6dfa8; color: #a16207; }
.pill-count { background: #f1f5f9; border-color: transparent; color: var(--muted); font-size: .76rem; padding: 3px 10px; }
.pill-plain { background: #fff; }

/* Verified chip — square-ish 8px radius, not a full pill (per the mockup). */
.verified {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 5px 12px;
    border-radius: var(--r-sm);
    background: var(--green-bg);
    color: var(--green-ink);
    font-size: .84rem;
    font-weight: 600;
    white-space: nowrap;
}
.verified .ico { width: 15px; height: 15px; }
.unverified { background: var(--line-soft); color: var(--dim); }

/* Green tab flag laid over the top border of the result card. */
.tag-found {
    display: inline-flex;
    align-items: center;
    padding: 7px 13px;
    background: var(--green-solid);
    color: #fff;
    border-radius: 5px;
    font-size: .74rem;
    font-weight: 800;
    letter-spacing: .07em;
    text-transform: uppercase;
    box-shadow: 0 2px 6px rgba(22, 163, 74, .3);
}

.verified-tick { width: 22px; height: 22px; color: var(--blue); flex: 0 0 auto; }

/* ------------------------------------------------------------ image frames */

/* Livery photography: fixed aspect, rounded, cover-cropped, never distorted. */
/* The frame matches the source artwork's own 600x335, and the image is
   contained rather than cropped. At 16/10 with object-fit: cover the frame was
   narrower than the art, so it trimmed the left and right edges — which on a
   side-on aeroplane means precisely the nose and the tail. */
.livery {
    position: relative;
    display: block;
    width: 100%;
    aspect-ratio: 600 / 335;
    overflow: hidden;
    border-radius: var(--r-ctl);
    background: linear-gradient(160deg, #dbe9fb, #c3daf6);
}
.livery > img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
}
.livery-wide { aspect-ratio: 16 / 9; }

/* Hero livery on an aircraft page. Capped at the source's own 600px width:
   stretching a 600x335 PNG across a 1360px container made it both enormous
   and visibly soft. Contain, not cover, so no wingtip is cropped. */
.livery-hero {
    width: 100%;
    max-width: 560px;
    margin-inline: auto;
    aspect-ratio: 600 / 335;
    background: linear-gradient(160deg, #eaf2fd, #dbe7f8);
}
.livery-hero > img { object-fit: contain; }
.livery-fixed { width: 248px; max-width: 100%; flex: 0 0 auto; }

/* Candidate picker: shown when one flight number was more than one flight. */
.choices { padding: 20px 22px 22px; }
.choices-head { margin: 0 0 4px; font-size: 1.06rem; }
.choices-sub { margin: 0 0 14px; color: var(--muted); font-size: .9rem; }
.choice {
    display: flex;
    flex-direction: column;
    gap: 3px;
    width: 100%;
    padding: 12px 14px;
    margin-bottom: 8px;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--r-ctl);
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.choice:last-child { margin-bottom: 0; }
.choice:hover { border-color: var(--blue); background: var(--blue-wash, #f4f8ff); }
.choice:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.choice-route { display: flex; align-items: center; gap: 9px; font-size: 1.02rem; }
.choice-route .ico { width: 16px; height: 16px; color: var(--blue); }
.choice-cities { color: var(--ink); font-size: .9rem; }
.choice-meta { color: var(--muted); font-size: .8rem; }

/* Scheduled against actual on the lookup card and the flight page. */
.fc-times {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 10px 0 0;
}
.fc-time {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin: 0;
    font-size: .86rem;
}
.fc-time-lbl {
    min-width: 68px;
    color: var(--muted);
    font-size: .78rem;
    text-transform: uppercase;
    letter-spacing: .04em;
}
.fc-time-sch { font-variant-numeric: tabular-nums; font-weight: 600; }
.fc-time-act {
    font-variant-numeric: tabular-nums;
    font-size: .8rem;
    padding: 1px 7px;
    border-radius: 999px;
}
.fc-time-act.is-late  { color: #92400e; background: #fef3c7; }
.fc-time-act.is-early { color: #065f46; background: #d1fae5; }

/* Caption under an unpainted stand-in, so it never reads as the real livery. */
.livery-note {
    margin: 6px 0 0;
    font-size: .74rem;
    line-height: 1.35;
    color: var(--muted);
    text-align: center;
}

/* Airline wordmark: contained, never stretched, ragged aspect ratios tolerated. */
.logo-mark {
    width: 100%; height: 100%;
    max-width: 100%; max-height: 100%;
    flex: 0 0 auto;
    object-fit: contain;
}
.logo-mark-lg { width: 100%; height: 100%; }

/* Small round member avatar for ranked rows (leaderboards, search results). */
.avatar-xs {
    display: grid;
    place-items: center;
    width: 28px; height: 28px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--blue);
    color: #fff;
    font-size: .72rem;
    font-weight: 800;
    object-fit: cover;
    overflow: hidden;
}
.logo-word {
    max-width: 100%;
    max-height: 64px;
    width: auto; height: auto;
    object-fit: contain;
}
.logo-fallback {
    display: grid;
    place-items: center;
    width: 100%; height: 100%;
    border-radius: inherit;
    background: var(--blue-soft);
    color: var(--blue);
    font-size: .82rem;
    font-weight: 800;
    letter-spacing: .02em;
}

/* Tinted chip behind a small aircraft side-view — a bare thumbnail at this
   size reads cheap, the chip is what makes the row look designed. */
.thumb-chip {
    display: grid;
    place-items: center;
    width: 76px; height: 44px;
    flex: 0 0 auto;
    overflow: hidden;
    border-radius: var(--r-btn);
    background: var(--chip);
}
@media (min-width: 640px) { .thumb-chip { width: 92px; height: 52px; } }
/* Liveries are 600x335 (~1.79:1) and the chip is ~1.77:1, so cover crops almost
   nothing and the whole aeroplane stays legible. A small square chip cropped
   this to an unreadable patch of fuselage. */
.thumb-chip > img { width: 100%; height: 100%; object-fit: cover; }
.thumb-chip .ico { width: 24px; height: 24px; color: var(--blue); }

/* -------------------------------------------------------- flight result card */

.flightcard { position: relative; overflow: visible; }
.flightcard .tag-found {
    position: absolute;
    top: -1px;
    left: 24px;
    z-index: 2;
}
.flightcard-body {
    display: flex;
    flex-direction: column;
    gap: 18px;
    padding: 34px 18px 20px;
}
.fc-logo { display: flex; align-items: center; min-height: 48px; }
.fc-logo > img { max-width: 100%; max-height: 56px; width: auto; height: auto; object-fit: contain; }
.fc-main { min-width: 0; flex: 1 1 auto; }
.fc-name {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
    margin: 0 0 12px;
    font-size: 1.25rem;
    font-weight: 700;
    letter-spacing: -.02em;
    color: var(--ink);
}
.fc-route {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 14px;
    margin-bottom: 12px;
    font-size: 1.12rem;
    font-weight: 600;
    color: var(--ink);
    line-height: 1.35;
}
.fc-route .code { color: var(--blue); }
.fc-route a { color: inherit; }
.fc-route a:hover { text-decoration: underline; }
.fc-route .ico { width: 20px; height: 20px; color: var(--blue); }
.fc-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 14px;
    color: var(--muted);
    font-size: .98rem;
}
.fc-meta .sep { color: var(--faint); }
.fc-photo { width: 100%; }

@media (min-width: 640px) {
    .flightcard-body { padding: 40px 24px 24px; }
}
/* The row needs ~590px of usable width for logo + identity + photograph. Inside
   .cols-main the main column is ~640px at a 1100px viewport, which leaves
   .fc-main about 106px, so the row is gated on the width at which the column can
   actually pay for it. The two fixed tracks may also shrink now rather than
   crushing the middle. */
@media (min-width: 1360px) {
    .flightcard-body {
        flex-direction: row;
        align-items: center;
        gap: 28px;
        padding: 34px 24px 30px;
    }
    .fc-logo { flex: 0 1 180px; min-width: 0; justify-content: flex-start; }
    .fc-photo { flex: 0 1 248px; min-width: 180px; }
    .fc-name { font-size: 1.4rem; }
    .fc-route { font-size: 1.3rem; }
}
/* .flightcard-wide marks a card in a full-width container (the Add Flight
   result), where the row fits from 860px as before. */
@media (min-width: 860px) {
    .flightcard-wide .flightcard-body {
        flex-direction: row;
        align-items: center;
        gap: 28px;
        padding: 34px 24px 30px;
    }
    .flightcard-wide .fc-logo { flex: 0 1 180px; min-width: 0; justify-content: flex-start; }
    .flightcard-wide .fc-photo { flex: 0 1 248px; min-width: 180px; }
    .flightcard-wide .fc-name { font-size: 1.4rem; }
    .flightcard-wide .fc-route { font-size: 1.3rem; }
}


/* --------------------------------------------------- divided icon spec strip */
/* The 6-cell strip under the flight hero: icon + small grey label on one line,
   the value on the line below, vertical hairlines between cells. */

.specstrip {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    border-top: 1px solid var(--line-soft);
}
.specstrip .spec {
    position: relative;
    padding: 16px 14px;
    min-width: 0;
}
/* vertical rule, inset from the top and bottom so it never touches an edge */
.specstrip .spec::before {
    content: "";
    position: absolute;
    left: 0; top: 14px; bottom: 14px;
    width: 1px;
    background: var(--line-soft);
}
/* horizontal rule between wrapped rows */
.specstrip .spec::after {
    content: "";
    position: absolute;
    top: 0; left: 14px; right: 14px;
    height: 1px;
    background: var(--line-soft);
}
.specstrip .spec:nth-child(2n + 1)::before { display: none; }
.specstrip .spec:nth-child(-n + 2)::after { display: none; }

.specstrip .spec-k {
    display: flex;
    align-items: center;
    gap: 11px;
    color: var(--muted);
    font-size: .88rem;
    font-weight: 500;
}
.specstrip .spec-k .ico { width: 18px; height: 18px; color: var(--muted); }
.specstrip .spec-v {
    margin-top: 6px;
    padding-left: 29px;         /* icon width + gap, so values align to labels */
    color: var(--ink-2);
    font-size: .95rem;
    font-weight: 600;
    hyphens: none;
}

@media (min-width: 640px) {
    .specstrip { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .specstrip .spec { padding: 18px 16px; }
    .specstrip .spec:nth-child(2n + 1)::before { display: block; }
    .specstrip .spec:nth-child(-n + 2)::after  { display: block; }
    .specstrip .spec:nth-child(3n + 1)::before { display: none; }
    .specstrip .spec:nth-child(-n + 3)::after  { display: none; }
}
/* The 6-up is a container question, not a viewport one: this strip lives in the
   main column of .cols-main, which is only ~640px wide at a 1100px viewport.
   Six tracks there leave ~41px of readable value width and shred the labels. */
@media (min-width: 1400px) {
    .specstrip { grid-template-columns: repeat(6, minmax(0, 1fr)); }
    .specstrip .spec { padding: 20px 18px 22px; }
    .specstrip .spec::after { display: none; }
    .specstrip .spec:nth-child(3n + 1)::before { display: block; }
    .specstrip .spec:first-child::before { display: none; }
    .specstrip .spec::before { top: 20px; bottom: 0; }
}
/* 4-cell variant (used where a flight has fewer facts) */
.specstrip-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 1024px) {
    .specstrip-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .specstrip-4 .spec:nth-child(3n + 1)::before { display: block; }
    .specstrip-4 .spec:first-child::before { display: none; }
}

/* ----------------------------------------------------------- stat displays */

/* Profile metric strip: blue icon over a big number over a grey label. */
.statrow {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 4px;
}
.statrow .s,
.statrow .stat {
    min-width: 0;
    overflow: hidden;
    position: relative;
    padding: 14px 8px;
    text-align: center;
    min-width: 0;
}
.statrow .ico { width: 24px; height: 24px; color: var(--blue); margin-bottom: 10px; vertical-align: 0; }
.statrow .n {
    display: block;
    font-size: 1.32rem;
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -.025em;
    font-variant-numeric: tabular-nums;
    color: var(--ink);
}
.statrow .l {
    display: block;
    margin-top: 5px;
    color: var(--muted);
    font-size: .82rem;
    font-weight: 500;
}
/* hairline grid so the strip does not read as loose text on a phone */
.statrow.gridlines .s::before,
.statrow.gridlines .stat::before {
    content: "";
    position: absolute;
    left: 0; top: 10px; bottom: 10px;
    width: 1px;
    background: var(--line-soft);
}
.statrow.gridlines .s:nth-child(2n + 1)::before,
.statrow.gridlines .stat:nth-child(2n + 1)::before { display: none; }

@media (min-width: 560px) {
    .statrow { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
    .statrow .n { font-size: 1.4rem; }
    .statrow.gridlines .s:nth-child(2n + 1)::before,
    .statrow.gridlines .stat:nth-child(2n + 1)::before { display: block; }
    .statrow.gridlines .s:nth-child(4n + 1)::before,
    .statrow.gridlines .stat:nth-child(4n + 1)::before { display: none; }
}
@media (min-width: 1024px) {
    .statrow { grid-template-columns: repeat(7, minmax(0, 1fr)); }
    .statrow .s, .statrow .stat { padding: 6px 8px 4px; }
    /* Seven centred tracks give ~86px of content each at 1024px, and a
       seven-figure mileage sets wider than that. A fixed 1.45rem overflowed
       .wrap and dragged a horizontal scrollbar onto the document. */
    .statrow .n { font-size: clamp(1.05rem, 1.6vw, 1.45rem); }
    .statrow.gridlines .s::before, .statrow.gridlines .stat::before { display: none; }
}
.statrow-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 560px) { .statrow-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
/* 3-cell variant (browse/airport.php). Declared after the 7-up block so source
   order wins, exactly as .statrow-4 does. */
.statrow-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 560px) { .statrow-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.statrow.boxed {
    padding: 14px 6px;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--r-card);
    box-shadow: var(--shadow-card);
}

/* The signature dark stat bar on the marketing page. Flat navy, rounded, inset
   hairlines between cells, no drop shadow — contrast alone does the work. */
.statbar {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    border-radius: 16px;
    background: var(--navy-2);
    color: #fff;
    overflow: hidden;
}
.statbar .s {
    position: relative;
    padding: 22px 12px;
    text-align: center;
    min-width: 0;
}
.statbar .s::before {
    content: "";
    position: absolute;
    left: 0; top: 20px; bottom: 20px;
    width: 1px;
    background: var(--line-dark);
}
.statbar .s::after {
    content: "";
    position: absolute;
    top: 0; left: 20px; right: 20px;
    height: 1px;
    background: var(--line-dark);
}
.statbar .s:nth-child(2n + 1)::before { display: none; }
.statbar .s:nth-child(-n + 2)::after { display: none; }
.statbar .s:nth-child(5) { grid-column: 1 / -1; }
.statbar .ico { width: 26px; height: 26px; margin-bottom: 14px; color: #1e6bf1; vertical-align: 0; }
.statbar .n {
    display: block;
    font-size: 1.4rem;
    font-weight: 700;
    letter-spacing: -.02em;
    line-height: 1.15;
    color: #fff;
}
.statbar .l { display: block; margin-top: 8px; color: #fff; font-size: .8rem; font-weight: 500; opacity: .92; }

@media (min-width: 760px) {
    .statbar { grid-template-columns: repeat(5, minmax(0, 1fr)); }
    .statbar .s { padding: 24px 14px 20px; }
    .statbar .s:nth-child(5) { grid-column: auto; }
    .statbar .s:nth-child(2n + 1)::before { display: block; }
    .statbar .s:first-child::before { display: none; }
    .statbar .s::after { display: none; }
    .statbar .s::before { top: 26px; bottom: 25px; }
    .statbar .n { font-size: 1.55rem; }
    .statbar .l { font-size: .84rem; }
}

/* Level panel — tinted, borderless, shadowless, with a hex medallion. */
.level-chip {
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 16px 20px;
    border-radius: var(--r-ctl);
    background: var(--level-bg);
}
.level-chip .hex { width: 48px; height: 50px; flex: 0 0 auto; font-size: 1.15rem; }
.level-chip .lv { font-size: 1.2rem; font-weight: 700; line-height: 1.2; letter-spacing: -.02em; color: var(--ink); }
.level-chip .nm { color: var(--blue); font-size: .98rem; font-weight: 600; }
@media (min-width: 1024px) { .level-chip { width: 214px; padding: 18px 24px; } }

/* Stats beside the level panel on wide screens, stacked below it on narrow. */
.stat-and-level { display: grid; gap: 18px; grid-template-columns: 1fr; align-items: center; }
/* The seven-cell strip only sits beside the 214px level chip once the row can
   pay for both; below that the chip drops onto its own line. */
@media (min-width: 1240px) { .stat-and-level { grid-template-columns: minmax(0, 1fr) auto; gap: 32px; } }

.level-bar { margin-top: 4px; }
.level-meta { display: flex; justify-content: space-between; gap: 12px; margin-bottom: 8px; color: var(--muted); font-size: .88rem; }
.level-meta strong { color: var(--ink); }
.track {
    height: 9px;
    border-radius: var(--r-pill);
    background: var(--line-soft);
    border: 1px solid var(--line);
    overflow: hidden;
}
.track > i {
    display: block;
    height: 100%;
    border-radius: var(--r-pill);
    background: linear-gradient(90deg, var(--blue), var(--violet-2));
}

/* ------------------------------------------------------------ points panel */

.points-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
    margin-bottom: 22px;
}
.points-head h2, .points-head h3, .points-head .card-h { margin: 0; font-size: 1.15rem; font-weight: 700; }
.points-head .total { color: var(--green); font-size: 1.15rem; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }

.points { list-style: none; margin: 0; padding: 0; }
.points li {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding: 9px 0;
    font-size: .98rem;
}
.points li > span:first-child { color: var(--muted); font-weight: 500; }
.points li > span:last-child {
    flex: 0 0 auto;
    color: var(--ink-2);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.points li.total {
    margin-top: 14px;
    padding-top: 22px;
    border-top: 1px solid var(--line-soft);
    font-size: 1.08rem;
}
.points li.total > span:first-child { color: var(--ink); font-weight: 700; }
.points li.total > span:last-child { color: var(--green); font-size: 1.2rem; font-weight: 700; }
.points .muted-row { color: var(--muted); font-size: .92rem; padding: 8px 0; }

/* legacy alias */
.points-panel .pp-head { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; margin-bottom: 20px; }
.points-panel .pp-head h3 { margin: 0; }
.points-panel .pp-total { color: var(--green); font-size: 1.15rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.points-panel ul { list-style: none; margin: 0; padding: 0; }
.points-panel li { display: flex; justify-content: space-between; gap: 16px; padding: 9px 0; font-size: .98rem; }
.points-panel li > span:first-child { color: var(--muted); font-weight: 500; }
.points-panel li > span:last-child { color: var(--ink-2); font-weight: 600; font-variant-numeric: tabular-nums; }
.points-panel li.total { margin-top: 14px; padding-top: 22px; border-top: 1px solid var(--line-soft); font-size: 1.08rem; }
.points-panel li.total > span:first-child { color: var(--ink); font-weight: 700; }
.points-panel li.total > span:last-child { color: var(--green); font-size: 1.2rem; font-weight: 700; }
.points-panel .muted-row { color: var(--muted); font-size: .92rem; padding: 8px 0; }

/* ---------------------------------------------------------------- notes */

/* A bordered inset panel on the same white as the card — the border alone
   separates it, no tint. */
.inset {
    padding: 16px;
    border: 1px solid var(--line-soft);
    border-radius: var(--r-ctl);
    background: #fff;
}
.note-panel { display: flex; gap: 16px; align-items: flex-start; }
.note-icon {
    display: grid;
    place-items: center;
    width: 48px; height: 48px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--blue-soft-2);
    color: var(--blue-ink);
}
.note-icon .ico { width: 22px; height: 22px; }
.note-body { min-width: 0; }
.note-body p { margin: 0; color: var(--ink-2); font-size: 1rem; line-height: 1.55; overflow-wrap: anywhere; }
.note-stamp { margin-top: 18px; color: var(--dim); font-size: .92rem; }

/* --------------------------------------------------------------- badges */

/* Hexagonal medallion, per the flight-record mockup: point-up hexagon, subtle
   top-lighter gradient, 2px white outline inset inside the shape. */
.hex {
    position: relative;
    display: grid;
    place-items: center;
    width: 72px; height: 74px;
    flex: 0 0 auto;
    color: #fff;
    clip-path: polygon(50% 0%, 96% 25%, 96% 75%, 50% 100%, 4% 75%, 4% 25%);
    background: linear-gradient(180deg, var(--violet-2), #4a2aa6);
}
.hex::before {
    content: "";
    position: absolute;
    inset: 5px;
    clip-path: polygon(50% 0%, 96% 25%, 96% 75%, 50% 100%, 4% 75%, 4% 25%);
    box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .85);
}
.hex .ico { width: 32px; height: 32px; vertical-align: 0; }
.hex-violet { background: linear-gradient(180deg, var(--violet-2), #4a2aa6); }
.hex-blue   { background: linear-gradient(180deg, #2f7bff, #0453ed); }
.hex-green  { background: linear-gradient(180deg, #1ba84b, #0d8e39); }
.hex-amber  { background: linear-gradient(180deg, #fbbf24, #d97706); }
.hex-rose   { background: linear-gradient(180deg, #fb7185, #be123c); }
.hex-slate  { background: linear-gradient(180deg, #94a3b8, #475569); }
.hex-sm { width: 48px; height: 50px; }
.hex-sm .ico { width: 22px; height: 22px; }
.hex-lg { width: 92px; height: 95px; }
.hex-lg .ico { width: 40px; height: 40px; }
.hex-locked { background: linear-gradient(180deg, #e2e8f0, #cbd5e1); color: #94a3b8; }
.hex-locked::before { box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .7); }

.medal-row {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
    justify-items: center;
    text-align: center;
}
.medal-row .cap {
    margin-top: 14px;
    color: var(--ink);
    font-size: .88rem;
    font-weight: 500;
    line-height: 1.35;
}
.medal { display: flex; flex-direction: column; align-items: center; min-width: 0; }
.badges-foot {
    margin-top: 24px;
    text-align: center;
    color: var(--muted);
    font-size: .98rem;
    font-weight: 500;
}
.badges-foot b { color: var(--green); font-weight: 700; }

.badge-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
@media (min-width: 640px)  { .badge-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; } }
@media (min-width: 1024px) { .badge-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.badge {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 20px 12px 18px;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--r-card);
    box-shadow: var(--shadow-card);
    text-align: center;
    transition: box-shadow .18s ease, transform .18s ease;
}
.badge:hover { box-shadow: var(--shadow-lift); }
.badge .name { margin-top: 12px; font-size: .93rem; font-weight: 700; letter-spacing: -.01em; }
.badge .desc { margin-top: 6px; color: var(--muted); font-size: .82rem; line-height: 1.45; }
/* --- earned: full colour, a ring in its tier, and the date it was won --- */
.badge-earned { background: #fff; }
.badge-earned.gold      { border-color: #f6dfa8; box-shadow: 0 0 0 3px #fdf6e6, var(--shadow-card); }
.badge-earned.legendary { border-color: #d5c9fb; box-shadow: 0 0 0 3px #f4f0ff, var(--shadow-card); }
.badge-won {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 12px;
    padding: 4px 11px;
    border-radius: 99px;
    background: var(--green-bg);
    color: var(--green-ink);
    font-size: .78rem;
    font-weight: 700;
}
.badge-won .ico { width: 13px; height: 13px; }

/* --- locked: drained of colour, dashed, and never tinted by tier --- */
.badge-locked {
    background: var(--bg-tint);
    border-style: dashed;
    border-color: var(--line);
    box-shadow: none;
}
.badge-locked .hex { filter: grayscale(1); opacity: .65; }
.badge-locked .name { color: var(--muted); }
.badge-locked .desc { color: var(--dim); }
.badge-locked:hover { box-shadow: none; border-color: var(--dim); }

/* Progress toward a locked badge, where the criteria are a single number. */
.badge-progress { width: 100%; margin-top: 14px; }
.badge-progress .track { height: 6px; }
.badge-progress-text {
    display: block;
    margin-top: 6px;
    color: var(--muted);
    font-size: .78rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------- tables */

.table { width: 100%; border-collapse: collapse; font-size: .93rem; }
.table th {
    padding: 12px 16px;
    background: var(--bg-tint);
    border-bottom: 1px solid var(--line-soft);
    color: var(--muted);
    font-size: .82rem;
    font-weight: 600;
    text-align: left;
    white-space: nowrap;
}
.table th:first-child, .table td:first-child { padding-left: 22px; }
.table th:last-child,  .table td:last-child  { padding-right: 22px; }
.table td {
    padding: 13px 16px;
    border-bottom: 1px solid var(--line-soft);
    color: var(--slate);
    vertical-align: middle;
}
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr { transition: background .12s ease; }
.table tbody tr:hover { background: var(--bg-tint); }
.table .num { text-align: right; font-variant-numeric: tabular-nums; font-weight: 500; }
.table .flightno { color: var(--blue); font-weight: 700; }
.table-scroll { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }

.route { display: inline-flex; align-items: center; gap: 10px; white-space: nowrap; font-weight: 600; color: var(--ink-2); }
.route .ico { width: 15px; height: 15px; color: var(--muted); }

/* Restacking table: give every <td> a data-label and add .table-stack.
   Below 640px each row becomes a labelled block; above it the table returns. */
@media (max-width: 639px) {
    .table-stack thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
    .table-stack tbody tr {
        display: block;
        padding: 14px 18px;
        border-bottom: 1px solid var(--line-soft);
    }
    .table-stack tbody tr:last-child { border-bottom: 0; }
    .table-stack td {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 16px;
        padding: 3px 0;
        border: 0;
        text-align: left;
    }
    .table-stack td::before {
        content: attr(data-label);
        flex: 0 0 auto;
        color: var(--dim);
        font-size: .8rem;
        font-weight: 500;
    }
    .table-stack td:first-child, .table-stack td:last-child { padding-left: 0; padding-right: 0; }
    .table-stack .num { text-align: right; }
}

/* --------------------------------------------------------- ranked lists */

.ranked { list-style: none; margin: 0; padding: 0; counter-reset: rank; }
.ranked li {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 13px 18px;
    border-bottom: 1px solid var(--line-soft);
    font-size: .95rem;
    transition: background .12s ease;
}
.ranked li:last-child { border-bottom: 0; }
.ranked li:hover { background: var(--bg-tint); }
@media (min-width: 640px) { .ranked li { padding: 14px 22px; min-height: 54px; } }

.ranked .rk, .ranked .rank {
    flex: 0 0 auto;
    width: 16px;
    color: var(--ink);
    font-size: .9rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.ranked .rank { counter-increment: rank; color: var(--muted); }
.ranked .rank::before { content: counter(rank); }
.ranked .ico-slot { display: flex; align-items: center; justify-content: center; width: 26px; flex: 0 0 auto; }

/* Logo plate. Airline wordmarks are 600x232 and airport marks are wide SVGs,
   so they need a LANDSCAPE box — squeezing them into a 28px square was what
   made them read as tiny slivers. The plate also gives a logo on a white
   background an edge, so it sits in the row instead of floating. */
.logo-slot {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 62px; height: 36px;
    flex: 0 0 auto;
    padding: 4px 6px;
    border: 1px solid var(--line-soft);
    border-radius: 8px;
    background: #fff;
    overflow: hidden;
}
@media (min-width: 640px) { .logo-slot { width: 78px; height: 44px; padding: 5px 8px; } }
.logo-slot > .ico { width: 20px; height: 20px; color: var(--muted); }
.ranked .nm, .ranked > li > a {
    min-width: 0;
    color: var(--slate);
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.ranked .meta {
    margin-left: auto;
    display: flex;
    gap: 20px;
    flex: 0 0 auto;
    color: var(--muted);
    font-size: .88rem;
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
.ranked .meta b { color: var(--ink-2); font-weight: 600; }
/* The value has to be able to shrink: its container (.card-flush) is
   overflow:hidden, so a nowrap value that cannot shrink is silently clipped at
   the card edge with no scrollbar and no ellipsis. */
.ranked .val {
    margin-left: auto;
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
/* on a phone the two right-aligned figures drop under the name */
@media (max-width: 559px) {
    .ranked li { flex-wrap: wrap; }
    .ranked .meta { width: 100%; margin-left: 58px; gap: 10px; text-align: left; font-size: .84rem; }
    .ranked .meta::before { content: none; }
}

/* ------------------------------------------------------------------ tabs */

.tabs {
    display: flex;
    gap: 4px;
    overflow-x: auto;
    scrollbar-width: none;
    border-bottom: 1px solid var(--line-soft);
    background: transparent;
    scroll-padding-left: var(--gutter);
}
.tabs::-webkit-scrollbar { display: none; }
.tabs a {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 14px 14px 15px;
    color: var(--muted);
    font-size: .96rem;
    font-weight: 500;
    white-space: nowrap;
    border-bottom: 3px solid transparent;
}
.tabs a:first-child { padding-left: 2px; }
.tabs a { scroll-snap-align: start; }
.tabs a:hover { color: var(--ink); text-decoration: none; }
.tabs a.active { color: var(--ink); font-weight: 700; border-bottom-color: var(--blue); }
.tabs a .pill-count { font-size: .74rem; }
@media (min-width: 1024px) { .tabs { gap: 18px; } .tabs a { padding: 16px 12px 17px; font-size: 1rem; } }
/* Below the desktop breakpoint the strip is wider than the window and its
   scrollbar is hidden, so it needs a cue: bleed to the viewport edge and fade
   the last 28px out, so a cut-off tab reads as "more this way". */
@media (max-width: 1023px) {
    .tabs {
        margin-inline: calc(var(--gutter) * -1);
        padding-inline: var(--gutter);
        scroll-snap-type: x proximity;
        -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent);
                mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent);
    }
}

/* --------------------------------------------------------------- profile */

.cover {
    position: relative;
    height: 110px;
    background-size: cover;
    background-position: center;
    overflow: hidden;
}
.cover > img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* The member's most-flown airline tail entering from the right, as in mockup
   (3). Decorative, clipped by the cover's own overflow. */
.cover .tail {
    position: absolute;
    right: -14px;
    bottom: -20px;
    width: 150px;
    height: auto;
    pointer-events: none;
    filter: drop-shadow(0 8px 18px rgba(6, 15, 30, .45));
}
@media (min-width: 640px)  { .cover .tail { width: 196px; right: 10px; bottom: -26px; } }
@media (min-width: 1024px) { .cover .tail { width: 236px; right: 40px; bottom: -30px; } }
@media (min-width: 640px)  { .cover { height: 140px; } }
@media (min-width: 1024px) { .cover { height: 170px; } }

.profile-bar { background: #fff; }

.profile-head {
    display: grid;
    grid-template-columns: 1fr;
    gap: 14px;
    padding-bottom: 22px;
}
.profile-head .avatar {
    display: grid;
    place-items: center;
    position: relative;
    width: 96px; height: 96px;
    margin-top: -44px;
    flex: 0 0 auto;
    border-radius: 50%;
    border: 5px solid #fff;
    background: var(--blue);
    color: #fff;
    font-size: 2.1rem;
    font-weight: 800;
    object-fit: cover;
    box-shadow: 0 4px 14px -6px rgba(15, 23, 42, .35);
}
.avatar-wrap { position: relative; width: max-content; }
/* The break-out lives on the wrapper now that the avatar is wrapped, so it is
   explicit rather than relying on margin collapsing through .avatar-wrap. */
.profile-head .avatar-wrap { margin-top: -44px; }
.profile-head .avatar-wrap > .avatar { margin-top: 0; }
.avatar-check {
    position: absolute;
    right: 2px; bottom: 2px;
    display: grid;
    place-items: center;
    width: 30px; height: 30px;
    border-radius: 50%;
    border: 3px solid #fff;
    background: #12283f;
    color: #fff;
}
.avatar-check .ico { width: 14px; height: 14px; }

.profile-head .who { min-width: 0; }
.profile-head .who h1 {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0 0 6px;
    font-size: 1.5rem;
}
.profile-head .who .sub {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 12px;
    color: var(--muted);
    font-size: .95rem;
}
.profile-head .who .sub a { display: inline-flex; align-items: center; gap: 7px; font-weight: 600; }
.profile-head .who .sub .ico { width: 16px; height: 16px; }
.profile-head .who .sub .dot { color: var(--faint); }
.profile-head .who .bio { margin: 12px 0 0; color: var(--slate); font-size: 1rem; font-weight: 500; }
.profile-head .acts { display: flex; flex-wrap: wrap; gap: 12px; }
.profile-head .acts > .btn { flex: 1 1 0; }

@media (min-width: 640px) {
    .profile-head .avatar { width: 132px; height: 132px; margin-top: -60px; font-size: 2.6rem; }
    .profile-head .avatar-wrap { margin-top: -60px; }
    .profile-head .avatar-wrap > .avatar { margin-top: 0; }
    .avatar-check { width: 34px; height: 34px; right: 6px; bottom: 6px; }
    .avatar-check .ico { width: 16px; height: 16px; }
    .profile-head .acts > .btn { flex: 0 0 auto; }
}
@media (min-width: 900px) {
    .profile-head {
        grid-template-columns: auto minmax(0, 1fr) auto;
        align-items: end;
        gap: 0 32px;
        padding-bottom: 26px;
    }
    .profile-head .avatar { width: 164px; height: 164px; margin-top: -84px; border-width: 6px; font-size: 3.2rem; }
    .profile-head .avatar-wrap { margin-top: -84px; }
    .profile-head .avatar-wrap > .avatar { margin-top: 0; }
    .avatar-check { width: 38px; height: 38px; right: 8px; bottom: 8px; }
    .profile-head .who { padding-bottom: 6px; }
    .profile-head .who h1 { font-size: 1.75rem; }
    .profile-head .acts { padding-bottom: 10px; }
}

/* Profile cover presets. The index is stored on the user row and rendered as a
   class, never as an inline style — the CSP forbids style attributes. */
.cover-0 { background-image: linear-gradient(180deg, rgba(255,255,255,.14), rgba(0,0,0,.14)), linear-gradient(115deg, #0b2a63, #1d4ed8 48%, #60a5fa); }
.cover-1 { background-image: radial-gradient(120% 140% at 20% 0%, rgba(255,255,255,.20), transparent 60%), linear-gradient(115deg, #0f172a, #334155 52%, #7c8da5); }
.cover-2 { background-image: radial-gradient(120% 140% at 78% 10%, rgba(255,255,255,.28), transparent 62%), linear-gradient(115deg, #7c2d12, #ea580c 55%, #fbbf24); }
.cover-3 { background-image: radial-gradient(110% 150% at 30% 5%, rgba(255,255,255,.22), transparent 60%), linear-gradient(115deg, #064e3b, #059669 55%, #6ee7b7); }
.cover-4 { background-image: radial-gradient(120% 140% at 70% 0%, rgba(255,255,255,.24), transparent 62%), linear-gradient(115deg, #3b1a86, #7c3aed 55%, #c4b5fd); }
.cover-5 { background-image: radial-gradient(120% 140% at 25% 0%, rgba(255,255,255,.26), transparent 60%), linear-gradient(115deg, #831843, #be185d 55%, #fbcfe8); }

.cover-picker { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
@media (min-width: 560px) { .cover-picker { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
.cover-opt { position: relative; }
.cover-opt input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.cover-opt span {
    display: block;
    height: 52px;
    border-radius: var(--r-btn);
    border: 3px solid transparent;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .08);
    background-size: cover;
    cursor: pointer;
}
.cover-opt input:checked + span { border-color: var(--blue); }
.cover-opt input:focus-visible + span { box-shadow: var(--ring); }

/* -------------------------------------------------- browse entity header */
/* Airline / airport / aircraft detail pages. NOT .profile-head: that avatar
   carries a negative margin so it can break out of a .cover, and there is no
   cover here — reusing it pulled the mark up behind the sticky nav. */
.entity-head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 18px;
    margin-bottom: 24px;
}
.entity-head .mark {
    display: grid;
    place-items: center;
    width: 76px; height: 76px;
    flex: 0 0 auto;
    padding: 12px;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--r-card);
    box-shadow: var(--shadow-card);
}
.entity-head .mark img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; }
.entity-head .mark .ico { width: 34px; height: 34px; color: var(--blue); }
.entity-head .who { min-width: 0; flex: 1 1 260px; }
.entity-head h1 { margin: 0; font-size: 1.5rem; letter-spacing: -.025em; }
.entity-head .meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 12px;
    margin: 9px 0 0;
    color: var(--muted);
    font-size: .96rem;
    font-weight: 500;
}
.entity-head .meta strong { color: var(--ink-2); font-weight: 700; }
.entity-head .meta .dot { color: var(--faint); }
@media (min-width: 640px) {
    .entity-head { gap: 22px; margin-bottom: 30px; }
    .entity-head .mark { width: 92px; height: 92px; padding: 14px; }
    .entity-head h1 { font-size: 1.9rem; }
}

/* ------------------------------------------------------------------ maps */

.map-wrap { position: relative; }
.map-box {
    width: 100%;
    height: 260px;
    border-radius: var(--r-ctl);
    overflow: hidden;
    background: #c3daf6;
    border: 1px solid var(--line);
}
.map-sm { height: 220px; }
.map-lg { height: 340px; }
@media (min-width: 640px)  { .map-box { height: 340px; } .map-sm { height: 254px; } .map-lg { height: 440px; } }
@media (min-width: 1024px) { .map-box { height: 420px; } .map-sm { height: 254px; } .map-lg { height: 520px; } }

/* Map that fills the bottom of a flush card: square top, card radius bottom. */
.map-flush { border: 0; border-radius: 0 0 var(--r-card) var(--r-card); }

.map-expand {
    position: absolute;
    right: 12px; bottom: 12px;
    z-index: 500;
    display: grid;
    place-items: center;
    width: 40px; height: 40px;
    border: 1px solid var(--line);
    border-radius: var(--r-btn);
    background: #fff;
    color: var(--ink);
    box-shadow: var(--shadow-pop);
    cursor: pointer;
}
.map-expand:hover { background: var(--bg-tint); text-decoration: none; }
.map-expand .ico { width: 18px; height: 18px; }
@media (min-width: 640px) { .map-expand { width: 36px; height: 36px; } }

.leaflet-container { background: #c3daf6 !important; }
.leaflet-control-attribution { font-size: 10px !important; }

/* ------------------------------------------------------------- marketing */

.hero {
    position: relative;
    display: grid;
    grid-template-columns: 1fr;
    gap: 28px;
    align-items: center;
    padding: 32px 0 8px;
}
.hero h1 {
    font-size: clamp(2.1rem, 8.5vw, 2.6rem);
    line-height: 1.12;
    letter-spacing: -.03em;
    margin-bottom: 16px;
}
.hero h1 .accent { color: #0d6cf4; }
.hero .lede { max-width: 34rem; margin-bottom: 26px; color: var(--slate); font-size: 1.05rem; line-height: 1.55; }
.hero .cta-row { margin-bottom: 30px; }
.hero-art { display: block; width: 100%; height: auto; }

/* Laptop frame around the product shot — mockup (1). The frame is decoration,
   so everything inside it is aria-hidden at the markup level. */
.device { position: relative; }
.device-screen {
    position: relative;
    border: 11px solid #1b2531;
    border-bottom-width: 13px;
    border-radius: 16px;
    background: #1b2531;
    box-shadow: var(--shadow-lift), 0 30px 50px -28px rgba(15, 23, 42, .55);
    overflow: hidden;
}
.device-chrome {
    display: flex;
    align-items: center;
    gap: 5px;
    height: 24px;
    padding: 0 10px;
    background: #f8fafc;
    border-bottom: 1px solid var(--line-soft);
}
.device-chrome i { display: block; width: 7px; height: 7px; border-radius: 50%; background: #cbd5e1; }
.device-chrome .ttl {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-left: 8px;
    color: var(--ink-2);
    font-size: .6rem;
    font-weight: 800;
    letter-spacing: -.01em;
}
.device-chrome .ttl .ico { width: 11px; height: 11px; color: var(--blue); }
.device-body { display: grid; grid-template-columns: 84px minmax(0, 1fr); background: #fff; }
.device-rail { padding: 7px 5px; border-right: 1px solid var(--line-soft); }
.device-rail span {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 3px 6px;
    border-radius: 5px;
    color: var(--muted);
    font-size: .56rem;
    font-weight: 600;
    line-height: 1.5;
}
.device-rail span .ico { width: 10px; height: 10px; flex: 0 0 auto; }
.device-rail span.on { background: var(--blue-soft); color: var(--blue-hover); }
.device-rail span.on .ico { color: var(--blue); }
.device-screen-art { display: block; width: 100%; height: auto; }
.device-base {
    position: relative;
    width: 112%;
    margin: 0 -6%;
    height: 11px;
    border-radius: 0 0 11px 11px;
    background: linear-gradient(180deg, #dbe2ea, #a9b4c2 55%, #7b8796);
    box-shadow: 0 16px 24px -16px rgba(15, 23, 42, .6);
}
.device-base::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 0;
    width: 78px;
    height: 5px;
    margin-left: -39px;
    border-radius: 0 0 6px 6px;
    background: rgba(15, 23, 42, .20);
}
@media (min-width: 640px) {
    .device-body { grid-template-columns: 104px minmax(0, 1fr); }
    .device-rail span { font-size: .64rem; gap: 7px; padding: 4px 7px; }
    .device-rail span .ico { width: 11px; height: 11px; }
    .device-chrome { height: 28px; }
    .device-chrome .ttl { font-size: .7rem; }
}
.hero-media { overflow: hidden; }

@media (min-width: 640px) {
    .hero { padding: 40px 0 12px; }
    .hero h1 { font-size: clamp(2.4rem, 5.6vw, 3.1rem); }
    .hero .lede { font-size: 1.12rem; }
}
@media (min-width: 1024px) {
    .hero { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: 40px; padding: 44px 0 16px; overflow: hidden; }
    .hero h1 { font-size: clamp(2.9rem, 3.9vw, 3.45rem); margin-bottom: 20px; }
    .hero .lede { font-size: 1.14rem; margin-bottom: 30px; }
}

.trust-row, .hero-trust {
    display: flex;
    flex-direction: column;
    gap: 12px;
    color: var(--muted);
    font-size: .92rem;
    font-weight: 500;
}
.trust-row span, .hero-trust span { display: inline-flex; align-items: center; gap: 10px; }
.trust-row .ico, .hero-trust .ico { width: 18px; height: 18px; color: #0d6cf4; }
@media (min-width: 560px) {
    .trust-row, .hero-trust { flex-direction: row; flex-wrap: wrap; gap: 20px 28px; }
}

.section { padding: 36px 0; }
@media (min-width: 1024px) { .section { padding: 48px 0; } }
.section h2 { font-size: clamp(1.4rem, 3.2vw, 1.75rem); margin-bottom: 14px; }
.section .lede { max-width: 42rem; color: var(--muted); font-size: 1rem; }

.split-media { display: grid; grid-template-columns: 1fr; gap: 28px; align-items: start; }
@media (min-width: 1024px) { .split-media { grid-template-columns: 400px minmax(0, 1fr); gap: 56px; } }

.feature-list { list-style: none; margin: 26px 0 0; padding: 0; }
.feature-list li { display: flex; gap: 14px; margin-bottom: 22px; }
.feature-list li:last-child { margin-bottom: 0; }
.feature-list .fi {
    display: grid;
    place-items: center;
    width: 40px; height: 40px;
    flex: 0 0 auto;
    border-radius: var(--r-btn);
    background: var(--blue-soft);
    color: var(--blue);
}
.feature-list .fi .ico { width: 20px; height: 20px; }
.feature-list b { display: block; color: var(--ink); font-size: 1rem; font-weight: 700; letter-spacing: -.01em; }
.feature-list span { display: block; margin-top: 3px; color: var(--dim); font-size: .93rem; line-height: 1.5; }

.band { margin-top: 40px; padding: 36px 0; background: #fff; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.band-blue { background: var(--blue-soft); border-color: var(--blue-line); }

/* Inset tinted band that sits on the page rather than bleeding to the edges. */
.band-inset {
    margin: 40px 0 0;
    padding: 28px 20px 34px;
    border-radius: 16px;
    background: var(--band);
}
@media (min-width: 640px)  { .band-inset { padding: 32px 28px 38px; } }
@media (min-width: 1024px) { .band-inset { padding: 34px 44px 42px; } }
.band-inset h2 { font-size: 1.25rem; font-weight: 700; margin-bottom: 20px; }

.quote-grid { display: grid; grid-template-columns: 1fr; gap: 16px; }
@media (min-width: 640px)  { .quote-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; } }
@media (min-width: 1024px) { .quote-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; } }

.quote-card {
    padding: 20px;
    background: #fff;
    border: 0;
    border-radius: var(--r-card);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .04), 0 6px 16px rgba(15, 23, 42, .05);
}
@media (min-width: 640px) { .quote-card { padding: 20px 24px 24px; } }
.quote-head { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; }
.quote-head .av {
    display: grid;
    place-items: center;
    width: 42px; height: 42px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--blue);
    color: #fff;
    font-weight: 800;
    object-fit: cover;
    overflow: hidden;
}
.quote-head .who { min-width: 0; }
.quote-head .who b { display: block; font-size: .98rem; font-weight: 700; }
.quote-head .who span { display: block; color: var(--dim); font-size: .84rem; font-weight: 500; }
.quote-head .stars { margin-left: auto; display: inline-flex; gap: 2px; color: var(--amber); }
.quote-head .stars .ico { width: 14px; height: 14px; }
.quote-card { margin: 0; }
.quote-card blockquote { margin: 0; }
.quote-card p { margin: 0; color: var(--slate); font-size: .95rem; line-height: 1.57; }
@media (max-width: 419px) { .quote-head { flex-wrap: wrap; } .quote-head .stars { margin-left: 54px; width: 100%; } }

.stars { display: inline-flex; gap: 2px; color: var(--amber); }
.stars .ico { width: 14px; height: 14px; }

/* --------------------------------------------------------------- alerts */

.alert {
    margin-bottom: 20px;
    padding: 14px 18px;
    border: 1px solid;
    border-radius: var(--r-ctl);
    font-size: .95rem;
}
.alert-error   { background: var(--red-bg); border-color: var(--red-line); color: #991b1b; }
.alert-success { background: #f0fdf4; border-color: var(--green-line); color: #166534; }
.alert-info    { background: var(--blue-soft); border-color: var(--blue-line); color: #1e40af; }

/* ------------------------------------------------------- empty + award */

.empty { padding: 44px 20px; text-align: center; color: var(--muted); }
/* Direct child only. `.empty .ico` and `.btn .ico` have the same specificity,
   so the later of the two won and blew the `+` inside an empty-state button
   up to 44px, stretching the button out of shape. */
.empty > .ico { width: 44px; height: 44px; color: var(--faint); margin-bottom: 14px; }

.award-hero { padding: 8px 0 4px; text-align: center; }
.award-hero .points { color: var(--green); font-size: clamp(2.6rem, 9vw, 3.8rem); font-weight: 800; line-height: 1; letter-spacing: -.04em; }
.award-hero .label { margin-top: 8px; color: var(--muted); font-size: .93rem; }
.award-list { list-style: none; margin: 22px auto 0; padding: 0; max-width: 460px; }
.award-list li {
    display: flex;
    justify-content: space-between;
    gap: 14px;
    padding: 11px 2px;
    border-bottom: 1px solid var(--line-soft);
    font-size: .96rem;
}
.award-list li:last-child { border-bottom: 0; }
.award-list .pts { color: var(--green); font-weight: 700; font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------- collections */

.collection-group { margin-bottom: 28px; }
.collection-group h3 { display: flex; align-items: baseline; gap: 10px; }
.collection-group h3 span { color: var(--muted); font-size: .84rem; font-weight: 600; }
.collection-list { display: grid; grid-template-columns: 1fr; gap: 8px; }
@media (min-width: 480px) { .collection-list { grid-template-columns: repeat(auto-fill, minmax(215px, 1fr)); } }
.collect-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 13px;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--r-btn);
    font-size: .9rem;
}
.collect-item .ico { width: 16px; height: 16px; color: var(--faint); }
.collect-item.got { border-color: var(--green-line); background: #f4fbf6; }
.collect-item.got .ico { color: var(--green); }
.collect-item.missing { background: var(--bg-tint); color: var(--dim); }
.collect-item .box { flex: 0 0 auto; }
.collect-item .dim { margin-left: auto; }

/* ------------------------------------------------------------- passport */

.stamp-grid { display: grid; grid-template-columns: 1fr; gap: 16px; }
@media (min-width: 480px) { .stamp-grid { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); } }
.stamp {
    padding: 18px;
    border: 2px dashed var(--blue-line);
    border-radius: var(--r-ctl);
    background: var(--blue-soft);
    transform: rotate(-.5deg);
}
.stamp:nth-child(even) { transform: rotate(.6deg); border-color: #f6dfa8; background: var(--amber-bg); }
.stamp .flag { line-height: 1; min-height: 30px; }

/* Real flag artwork, not the regional-indicator emoji this used to be.
   Windows has no glyphs for those pairs, so a browser there fell back to
   drawing the two letters — which is why a passport full of stamps read
   "TR US ES CH IT" rather than showing any flags at all. */
.flag-img {
    display: block;
    width: 40px;
    height: auto;
    border-radius: 3px;
    box-shadow: 0 0 0 1px rgba(15, 32, 56, .12);
}
.flag-inline {
    display: inline-block;
    width: 20px;
    height: auto;
    vertical-align: -3px;
    margin-right: 2px;
    border-radius: 2px;
    box-shadow: 0 0 0 1px rgba(15, 32, 56, .12);
}
.stamp .country { margin-top: 8px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; }
.stamp .meta { margin-top: 7px; color: var(--muted); font-size: .82rem; line-height: 1.6; }
.stamp .codes { margin-top: 9px; color: var(--faint); font-size: .78rem; }

/* --------------------------------------------------------------- footer */

.site-footer {
    margin-top: 56px;
    /* Sized for the four-column footer, not the old one-line strip. The bottom
       value is the smaller of the pair because `.footer-bar` now contributes
       its own 20px of padding-top above the copyright. */
    padding: 40px 0 24px;
    background: #fff;
    border-top: 1px solid var(--line);
    color: var(--muted);
    font-size: .92rem;
}
@media (min-width: 640px)  { .site-footer { padding: 48px 0 28px; } }
@media (min-width: 1024px) { .site-footer { padding: 56px 0 32px; } }

/* The generic strip layout, kept for any footer .wrap that is not one of the
   two structured rows below. */
.site-footer .wrap { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 14px 20px; }
.site-footer a { color: var(--muted); }
.site-footer a:hover { color: var(--ink); }

/* Row 1 — brand block beside four link columns.
   MUST be (0,3,0): a bare `.footer-top` is (0,1,0) and loses to
   `.site-footer .wrap` (0,2,0) above, which would flatten the whole footer
   back into a single wrapping flex line. */
.site-footer .wrap.footer-top {
    display: grid;
    grid-template-columns: 1fr;
    gap: 28px;
    text-align: left;
}
@media (min-width: 640px) {
    .site-footer .wrap.footer-top { gap: 32px; }
}
@media (min-width: 1024px) {
    .site-footer .wrap.footer-top {
        grid-template-columns: minmax(240px, 320px) minmax(0, 1fr);
        gap: 48px;
        align-items: start;
    }
}
@media (min-width: 1240px) {
    .site-footer .wrap.footer-top {
        grid-template-columns: minmax(280px, 360px) minmax(0, 1fr);
        gap: 64px;
    }
}

.footer-brand { display: block; max-width: 34ch; }

/* The footer wordmark. Deliberately not `.brand`, which is `color: #fff` and
   therefore invisible on a white footer (its ink override is scoped to
   `.topnav-light`). Scoped to `.site-footer` so it beats `.site-footer a`
   (0,2,0) rather than tying with it at (0,1,0). Kept a step below the
   header wordmark 1.45rem so the footer stays the quieter of the two. */
.site-footer .footer-mark {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    color: var(--ink);
    font-size: 1.22rem;
    font-weight: 800;
    letter-spacing: -.025em;
    white-space: nowrap;
}
.site-footer .footer-mark:hover { color: var(--ink); text-decoration: none; }
.site-footer .footer-mark .ico { width: 26px; height: 26px; color: var(--blue-bright); vertical-align: 0; }
@media (min-width: 1024px) {
    .site-footer .footer-mark { font-size: 1.32rem; }
    .site-footer .footer-mark .ico { width: 29px; height: 29px; }
}

/* `margin: 12px 0 0` is load-bearing: the reset gives `p { margin: 0 0 1em }`,
   and that trailing margin inside a grid cell throws the columns out of
   alignment on mobile. */
.footer-tagline {
    margin: 12px 0 0;
    max-width: 34ch;
    color: var(--muted);
    font-size: .92rem;
    line-height: 1.6;
}

.footer-cols {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 24px 20px;
}
/* Four columns: Discover / Browse / More from us / Your logbook. About,
   Privacy and Terms deliberately stay out of here — they live in
   `.footer-legal` in the bottom bar, where they are conventional and where
   they give `space-between` its second anchor. Two-up on small screens keeps
   the pairs even rather than leaving one column stranded on its own row. */
@media (min-width: 640px)  { .footer-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 24px; } }
@media (min-width: 900px)  { .footer-cols { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 28px 24px; } }
@media (min-width: 1024px) { .footer-cols { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 32px; } }

.footer-col { min-width: 0; }

/* Must not inherit the h2 display type: the reset gives 1.25rem/800, far too
   loud for a column label. Identical at every breakpoint on purpose, and
   matched to the `.navmenu .head` treatment so the two read as one system. */
.footer-head {
    margin: 0 0 12px;
    color: var(--ink);
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    line-height: 1.2;
}

/* There is no global list reset in this sheet, so the list supplies its own. */
.footer-list { list-style: none; margin: 0; padding: 0; }
.footer-list li + li { margin-top: 9px; }
@media (min-width: 640px) { .footer-list li + li { margin-top: 10px; } }
.footer-list a { color: var(--muted); font-size: .92rem; line-height: 1.5; }
.footer-list a:hover { color: var(--ink); }

/* Row 2 — the copyright bar. Again (0,3,0) so it beats `.site-footer .wrap`.
   `padding-top` is written long-hand, never as the `padding` shorthand, so
   the `.wrap` horizontal gutter survives; the hairline therefore spans the
   1360px container rather than the full viewport. */
.site-footer .wrap.footer-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px 20px;
    margin-top: 24px;
    padding-top: 20px;
    border-top: 1px solid var(--line-soft);
    color: var(--faint);
    font-size: .86rem;
}
@media (min-width: 640px)  { .site-footer .wrap.footer-bar { margin-top: 32px; } }
@media (min-width: 1024px) { .site-footer .wrap.footer-bar { margin-top: 36px; } }

/* The bar's second anchor: with one child, `space-between` above left the
   copyright alone against ~1000px of dead space under a full-width hairline
   that visually promises two ends. Must be (0,3,0) on the anchors to beat
   `.site-footer a` (0,2,0), same reason as `.footer-mark`. */
.footer-legal {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 20px;
}
.site-footer .footer-legal a { color: var(--faint); font-size: .86rem; }
.site-footer .footer-legal a:hover { color: var(--ink); text-decoration: none; }

.skip-link { position: absolute; left: -9999px; top: 0; z-index: 100; padding: 11px 18px; background: var(--blue); color: #fff; }
.skip-link:focus { left: 0; }
.logout-form { display: inline; margin: 0; }

/* ------------------------------------------------------------ utilities */

.muted { color: var(--muted); }
.dim   { color: var(--faint); }
.small { font-size: .88rem; }
.tiny  { font-size: .8rem; }
.center { text-align: center; }
.right  { text-align: right; }
.nowrap { white-space: nowrap; }
.tabnum { font-variant-numeric: tabular-nums; }
.green  { color: var(--green); }
.blue   { color: var(--blue); }
.bold   { font-weight: 700; }

.mt    { margin-top: 20px; }
.mt-sm { margin-top: 12px; }
.mt-lg { margin-top: 34px; }
.mb    { margin-bottom: 20px; }
.mb-sm { margin-bottom: 12px; }
.mb-lg { margin-bottom: 34px; }
.mt-0  { margin-top: 0; }
.mb-0  { margin-bottom: 0; }

.flex     { display: flex; gap: 12px; align-items: center; }
.flex-between { display: flex; gap: 12px; align-items: center; justify-content: space-between; }
.flex-wrap { flex-wrap: wrap; }
.push     { margin-left: auto; }
.hide     { display: none; }
.sr-only {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.only-sm { display: revert; }
@media (max-width: 639px)  { .hide-sm { display: none !important; } }
@media (min-width: 640px)  { .only-sm { display: none !important; } }
@media (max-width: 1023px) { .hide-md-down { display: none !important; } }
@media (min-width: 1024px) { .only-md-down { display: none !important; } }

/* Progress and meter widths. Classes, not inline styles, because the CSP
   forbids style attributes. */
.w-0{width:0}.w-5{width:5%}.w-10{width:10%}.w-15{width:15%}.w-20{width:20%}
.w-25{width:25%}.w-30{width:30%}.w-35{width:35%}.w-40{width:40%}.w-45{width:45%}
.w-50{width:50%}.w-55{width:55%}.w-60{width:60%}.w-65{width:65%}.w-70{width:70%}
.w-75{width:75%}.w-80{width:80%}.w-85{width:85%}.w-90{width:90%}.w-95{width:95%}
.w-100{width:100%}

@media (prefers-reduced-motion: reduce) {
    * { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
    .btn:active { transform: none; }
}

/* Share button confirmation. The label swaps to "Link copied" for a moment,
   so the click has visible feedback instead of appearing to do nothing. */
.btn.is-shared { border-color: var(--green-line); color: var(--green-ink); background: var(--green-bg); }
.visually-hidden {
    position: absolute !important;
    width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

/* ------------------------------------------------------- aircraft collection
   The collection leads with what has actually been flown: one card per type,
   carrying the livery of the airline the member flew it with most. */
.fleet-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1px;
    background: var(--line-soft);
    border-top: 1px solid var(--line-soft);
}
@media (min-width: 720px)  { .fleet-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1180px) { .fleet-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.fleet-card {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 18px;
    background: var(--card);
    color: inherit;
    min-width: 0;
}
.fleet-card:hover { background: var(--bg-tint); text-decoration: none; }

/* Liveries are 600x335; the chip matches that ratio so nothing is cropped. */
.fleet-shot {
    display: grid;
    place-items: center;
    width: 96px; height: 54px;
    flex: 0 0 auto;
    overflow: hidden;
    border-radius: var(--r-btn);
    background: var(--chip);
}
.fleet-shot > img { width: 100%; height: 100%; object-fit: cover; }

.fleet-body { min-width: 0; flex: 1 1 auto; }
.fleet-name {
    display: block;
    font-weight: 600;
    color: var(--ink);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fleet-meta {
    display: block;
    margin-top: 2px;
    color: var(--muted);
    font-size: .84rem;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fleet-count { flex: 0 0 auto; text-align: right; line-height: 1.2; }
.fleet-count b { display: block; font-size: 1.05rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.fleet-count span { font-size: .78rem; color: var(--muted); }

/* Everything not yet collected, folded away so it cannot dominate the page. */
.collect-more { border-top: 1px solid var(--line); }
.collect-more > summary {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 15px 18px;
    cursor: pointer;
    color: var(--muted);
    font-weight: 600;
    font-size: .92rem;
    list-style: none;
}
.collect-more > summary::-webkit-details-marker { display: none; }
.collect-more > summary:hover { color: var(--ink); background: var(--bg-tint); }
.collect-more[open] > summary { border-bottom: 1px solid var(--line-soft); color: var(--ink); }
.collect-more-body { padding: 18px; }

/* --------------------------------------------- homepage: closing section
   "Why keep a logbook" — a labelled set of three pillar cards, then the
   closing offer. The three cards were the ones the client called out as not
   centred: half of that was the `.card + .card` grid-sibling margin fixed
   near the top of this sheet, the other half is that the cards were
   left-aligned, so three paragraphs of different lengths were the only thing
   establishing the alignment. They are centred on their own axis now, with
   the hexagon as the shared datum and a chip on the last line as the shared
   closing anchor. */

.pillars-head {
    max-width: 46rem;
    margin: 0 auto 24px;
    text-align: center;
}
@media (min-width: 640px)  { .pillars-head { margin-bottom: 30px; } }
@media (min-width: 1024px) { .pillars-head { margin-bottom: 36px; } }

/* Matched to `.section h2` so this closing section reads at the same rank as
   "See your journey come to life" above it. The clamp covers all three
   breakpoints, so no media query is needed. */
.pillars-head h2 {
    margin: 0 0 10px;
    color: var(--ink);
    font-size: clamp(1.4rem, 3.2vw, 1.75rem);
    font-weight: 700;
    letter-spacing: -.02em;
    line-height: 1.2;
}
/* `.lede` is not defined globally — only `.hero .lede` and `.section .lede`
   exist — so the supporting line needs its own scoped rule. */
.pillars-head p {
    max-width: 42rem;
    margin: 0 auto;
    color: var(--muted);
    font-size: .98rem;
    line-height: 1.55;
}
@media (min-width: 640px)  { .pillars-head p { font-size: 1rem; } }
@media (min-width: 1024px) { .pillars-head p { font-size: 1.05rem; } }

/* A modifier on the `.cols-3` grid, not a replacement: the 1 / 2 / 3 column
   progression `.cols-3` already gives is correct here. Its only job is to
   make every card fill the row height, which is what lets `.pillar-note` line
   up across the set. The lone third card at tablet width deliberately stays
   in column 1 at normal width — identical card widths read better than a
   centred orphan. */
.pillars { align-items: stretch; }

/* (0,3,0). `.pillar` alone is (0,1,0) and would lose to
   `.cols-3 > .card { align-items: flex-start }` (0,2,0) regardless of source
   order — the cards would silently stay left-aligned. */
.pillars > .card.pillar {
    display: flex;
    flex-direction: column;
    align-items: center;
    height: 100%;
    padding: 24px 20px 22px;
    text-align: center;
}
@media (min-width: 640px)  { .pillars > .card.pillar { padding: 28px 24px 24px; } }
@media (min-width: 1024px) { .pillars > .card.pillar { padding: 32px 26px 26px; } }

/* The hexagon is the alignment datum for the set, so its size is constant at
   every breakpoint and the gap below it — not a utility class on the heading
   — is what sets the headings on a common baseline. */
.pillars > .card.pillar > .hex {
    flex: 0 0 auto;
    align-self: center;
    margin: 0 0 14px;
}
@media (min-width: 640px)  { .pillars > .card.pillar > .hex { margin-bottom: 16px; } }
@media (min-width: 1024px) { .pillars > .card.pillar > .hex { margin-bottom: 18px; } }

.pillar-title {
    margin: 0 0 10px;
    color: var(--ink);
    font-size: 1.08rem;
    font-weight: 700;
    letter-spacing: -.015em;
    line-height: 1.25;
    text-align: center;
}
@media (min-width: 1024px) { .pillar-title { font-size: 1.15rem; } }

/* (0,4,0). `flex: 1 1 auto` has to beat `.cols-3 > .card > p { flex: 1 0 auto }`
   (0,3,0): the paragraph absorbing the leftover height is what pushes
   `.pillar-note` to the same y position in all three cards. The ch cap keeps
   the measure readable; it does NOT prevent an orphan last line — only the
   copy can do that, so keep the three paragraphs within a few characters of
   each other (they are ~104 now) and re-check the last line if you edit one. */
.pillars > .card.pillar > .pillar-copy {
    flex: 1 1 auto;
    max-width: none;
    margin: 0;
    color: var(--muted);
    font-size: .95rem;
    line-height: 1.6;
    text-align: center;
}
@media (min-width: 640px) {
    .pillars > .card.pillar > .pillar-copy { max-width: 30ch; margin-inline: auto; }
}
@media (min-width: 1024px) {
    .pillars > .card.pillar > .pillar-copy { max-width: 32ch; }
}

/* One neutral treatment on all three cards even though the hexagons are
   blue / violet / green: the shared chip is what makes the set read as
   deliberate. It needs no `margin-top: auto` — the copy above grows into the
   slack instead, and an auto margin would fight that. */
.pillar-note {
    display: inline-block;
    margin-top: 16px;
    padding: 5px 11px;
    border-radius: var(--r-pill);
    background: var(--blue-soft);
    color: var(--blue);
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .02em;
    line-height: 1.2;
    white-space: nowrap;
}
@media (min-width: 640px)  { .pillar-note { margin-top: 18px; padding: 6px 12px; font-size: .76rem; } }
@media (min-width: 1024px) { .pillar-note { margin-top: 20px; font-size: .78rem; } }
/* Below 380px the longest chip would otherwise push the card out. */
@media (max-width: 379px)  { .pillar-note { white-space: normal; } }

/* The closing beat. Deliberately NOT a `.card`: tinted rather than white, so
   it reads as heavier and warmer than the three cards above it — and, as a
   side effect, it is immune to the `.card + .card` margin entirely. It
   carries `.mt-lg` in the markup, so no top margin is set here. */
.closer {
    position: relative;
    overflow: hidden;
    padding: 32px 20px 28px;
    border: 1px solid var(--blue-line);
    border-radius: var(--r-card);
    background: linear-gradient(180deg, var(--blue-soft), #fff);
    box-shadow: var(--shadow-card);
    text-align: center;
}
@media (min-width: 640px)  { .closer { padding: 40px 32px 34px; } }
@media (min-width: 1024px) { .closer { padding: 48px 40px 40px; } }

/* The base `.hex` uses clip-path, and box-shadow does not follow a clip-path
   — a drop-shadow filter does, so the medallion keeps its hexagonal edge. */
.closer-hex {
    width: 56px; height: 58px;
    margin: 0 auto 14px;
    filter: drop-shadow(0 8px 16px rgba(13, 92, 226, .22));
}
.closer-hex .ico { width: 25px; height: 25px; }
@media (min-width: 640px) {
    .closer-hex { width: 64px; height: 66px; margin-bottom: 18px; }
    .closer-hex .ico { width: 28px; height: 28px; }
}
@media (min-width: 1024px) {
    .closer-hex { width: 72px; height: 74px; margin-bottom: 20px; }
    .closer-hex .ico { width: 32px; height: 32px; }
}

/* Visibly louder than `.pillars-head h2` — this is the last word on the page. */
.closer-title {
    margin: 0 0 10px;
    color: var(--ink);
    font-size: clamp(1.4rem, 4vw, 1.9rem);
    font-weight: 800;
    letter-spacing: -.02em;
    line-height: 1.15;
}

/* --slate, not --muted: on the tinted panel the muted grey goes weak. */
.closer-lede {
    max-width: none;
    margin: 0 auto 20px;
    color: var(--slate);
    font-size: .98rem;
    line-height: 1.55;
    text-align: center;
}
@media (min-width: 640px)  { .closer-lede { max-width: 34rem; margin-bottom: 24px; font-size: 1.02rem; } }
@media (min-width: 1024px) { .closer-lede { margin-bottom: 28px; font-size: 1.1rem; } }

/* The base `.cta-row` is left-aligned, which leaves the pair hanging off the
   axis inside a centred panel. Everything else about `.cta-row` is kept: the
   buttons stack full width below 480px, primary first. */
.closer-cta { justify-content: center; margin-bottom: 0; }

.closer .reassure { margin-top: 18px; flex-wrap: wrap; color: var(--slate); font-size: .88rem; text-align: center; }
.closer .reassure .ico { color: var(--blue); opacity: .8; }
@media (min-width: 640px) { .closer .reassure { margin-top: 20px; font-size: .93rem; } }

/* Analytics beacon. The vendor snippet carries these as an inline style
   attribute, which style-src forbids without 'unsafe-inline'. Same effect,
   kept out of the markup so the CSP stays strict. */
.tracking-px {
    position: absolute;
    width: 1px;
    height: 1px;
    border: 0;
    visibility: hidden;
}

/* ------------------------------------------------------------------ admin
   Deliberately plain: this is an operator surface, not a marketing one. It
   reuses .card / .ranked / .table wholesale and adds only what moderation
   needs — action clusters and an inline confirm. */
.admin-actions { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; }
.admin-actions form { display: inline; margin: 0; }

/* Inline confirm for destructive actions. A <details> rather than a JS
   confirm(): the CSP forbids the inline handler, and this keeps the warning
   and the button in the same place so the consequence is read before the
   click. */
.confirm { position: relative; display: inline-block; }
.confirm > summary { list-style: none; cursor: pointer; }
.confirm > summary::-webkit-details-marker { display: none; }
.confirm-body {
    position: absolute;
    right: 0;
    z-index: 30;
    width: 260px;
    margin-top: 8px;
    padding: 14px;
    text-align: left;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--r-card);
    box-shadow: var(--shadow-lift);
}
.confirm-body p { margin: 0 0 12px; color: var(--muted); }
@media (max-width: 640px) {
    .confirm { position: static; }
    .confirm-body { position: static; width: auto; }
}

.admin-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 0 18px 16px;
    border-bottom: 1px solid var(--line-soft);
}
.admin-filters form { flex: 1 1 260px; max-width: 380px; margin: 0; }
@media (min-width: 640px) { .admin-filters { padding: 0 22px 18px; } }

.chip-tabs { display: flex; flex-wrap: wrap; gap: 6px; }
.chip-tab {
    padding: 7px 14px;
    border: 1px solid var(--line);
    border-radius: 99px;
    color: var(--muted);
    font-size: .87rem;
    font-weight: 600;
}
.chip-tab:hover { border-color: var(--dim); color: var(--ink); text-decoration: none; }
.chip-tab.active { background: var(--blue); border-color: var(--blue); color: #fff; }

.pill-danger { background: var(--red-bg); border-color: #f6c9c9; color: var(--red); }

.table code, .ranked code {
    padding: 2px 6px;
    background: var(--bg-tint);
    border: 1px solid var(--line-soft);
    border-radius: 5px;
    font-size: .84rem;
}
