/* ── 16 · INFORMATION — JOIN TAB ──
   The level explorer (information/join.js).

   Part of the numbered set in css/ — the sheets are one stylesheet cut into
   pieces and index.html links them in this order. Order is the cascade: a
   rule here loses to the same-specificity rule in any later file. */

/* ─────────────────────────────────────
   JOIN TAB — the level explorer
   Markup is built by information/join.js; copy lives in join-content.js.

   Everything here sits over the same photographic backdrop the Contact tab
   floats on, so it uses the same glass recipe: a frosted sheet at ~0.8 alpha
   with a blur behind it, which is what keeps the text legible over the image.
   Three sheets stack — the console (intro + rail), the active stage, the
   outro — with the smaller pieces inside them on a lighter, unblurred wash so
   the blur is only ever paid for once per sheet.

   Colour is per level, not per section: join.js writes --join-accent / --deep
   / --ink onto .join from the level's own palette, and onto each rail button
   from *its* level's, so the rail reads as three coloured steps while the
   panel below follows only the active one. The triplets below are the
   fallback the stylesheet paints with before that runs.

   Custom properties do not transition, but the declarations that read them do,
   so a level change eases its colours across rather than snapping.
───────────────────────────────────── */
.join {
    --join-accent: 255, 85, 85;
    --join-deep: 162, 44, 44;
    --join-ink: 126, 47, 47;
    /* The surface the rail's tiles are painted on. They are fully opaque — see
       .join-step — and every tint on them is mixed against this rather than
       being an alpha over it. */
    --join-surface: #fbfaf7;
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.join-block__title,
.join-stage__eyebrow,
.join-outro__kicker,
.join-route__meta,
.join-note__title,
.join-route__highlights li,
.join-filter,
.join-note,
.join-step-item,
.join-step-item::before,
.join-faq__question::after,
.join-ladder::before,
.join-link {
    transition:
        color 0.35s ease,
        background-color 0.35s ease,
        border-color 0.35s ease;
}

/* Shared with the Services tab, so the level tint has to be reapplied here
   rather than changing .contact-cta itself. */
.join-outro__actions .contact-cta {
    border-color: rgba(var(--join-ink), 0.18);
    color: rgb(var(--join-ink));
}

.join-outro__actions .contact-cta:hover {
    border-color: rgba(var(--join-ink), 0.32);
    box-shadow: 0 12px 28px rgba(var(--join-ink), 0.12);
}

.join-outro__actions .contact-cta--primary {
    background: linear-gradient(135deg, rgba(var(--join-accent), 0.92), rgba(var(--join-deep), 0.95));
    border-color: transparent;
    color: #fff7f5;
}

.join-console,
.join-stage,
.join-outro {
    background: rgba(252, 251, 248, 0.82);
    backdrop-filter: blur(6px) saturate(1.08);
    -webkit-backdrop-filter: blur(6px) saturate(1.08);
    border: 1px solid rgba(255, 255, 255, 0.75);
    border-radius: 26px;
    box-shadow: 0 26px 60px rgba(17, 17, 17, 0.16);
}

.join-console {
    padding: 1.9rem 2.2rem 1.7rem;
}

.join-console__prompt {
    text-align: center;
    font-family: Georgia, "Times New Roman", serif;
    font-size: clamp(1.35rem, 2.2vw, 1.9rem);
    font-weight: 700;
    line-height: 1.15;
    color: #1a1a1a;
}

/* ── The rail ──
   One tile per level, laid out as equal columns. The tiles are opaque, so the
   connecting line behind them shows only in the gaps and reads as a connector
   between steps rather than a line running under them.

   --join-col (a column's width) and --join-pitch (the distance between two
   column centres) are the only two measurements the line and its progress fill
   need to place themselves, so JS still writes --join-active and nothing else.
   Both are written with the gap subtracted out — with `gap: 0` a centre would
   sit at the simpler (i + 0.5) / count, but the tiles need the gap for the line
   to be visible at all. */
.join-ladder {
    --join-gap: 0.6rem;
    --join-col: calc((100% - (var(--join-count) - 1) * var(--join-gap)) / var(--join-count));
    --join-pitch: calc(var(--join-col) + var(--join-gap));
    position: relative;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: var(--join-gap);
    margin-top: 1.5rem;
}

.join-ladder::before,
.join-ladder::after {
    content: "";
    position: absolute;
    /* The tiles are grid items in a single row and stretch to a common height,
       so the row's midline is also theirs whatever the labels wrap to. */
    top: 50%;
    margin-top: -1px;
    height: 2px;
    border-radius: 2px;
}

.join-ladder::before {
    left: calc(var(--join-col) / 2);
    right: calc(var(--join-col) / 2);
    background: rgba(var(--join-ink), 0.16);
}

.join-ladder::after {
    left: calc(var(--join-col) / 2);
    width: calc(var(--join-pitch) * var(--join-active, 0));
    background: linear-gradient(90deg, rgba(var(--join-accent), 0.55), rgba(var(--join-deep), 0.85));
    transition: width 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

@media (prefers-reduced-motion: reduce) {
    .join-ladder::after {
        transition: none;
    }
}

/* The tile. The whole button is the rounded square and the level's name sits
   inside it, so there is no separate node to place a number in.

   Capped in width rather than filling its column: three full-width columns
   would each be a wide bar, and the connecting line would have nowhere to show.
   Centred in the column, so the line's endpoints — which are placed at the
   column centres — still land on the tiles.

   A rectangle, not a square: the label is one or two short lines, and a tile
   tall enough to be square is mostly empty. min-height rather than height so a
   label that does wrap grows the tile instead of spilling out of it.

   Nothing here may use `box-shadow`, and nothing here may sit outside the
   tile's own edges. A shadow — or any element that needs its own compositing
   layer, which is also why there is no `scale()` on the active tile — gets its
   own render surface inside .join-console's backdrop-filter, and Chrome then
   re-samples the blurred backdrop over that surface's *rectangular* bounds. An
   earlier `0 0 0 5px` halo showed up not as a ring but as a hard-edged pale
   rectangle; a painted pseudo-element ring instead of a shadow avoided that,
   but still read as a bezel around the active tile. So the selected state is
   the tile itself and nothing around it.

   Fully opaque, fill and border alike. .join-console is a frosted sheet over
   the section's photograph, so any alpha here let that photograph read through
   the tile — the resting tiles picked up the backdrop's tone and the selected
   one was washed out by it. Tints are mixed against --join-surface instead. */
.join-step {
    /* Above the rail's ::after, which would otherwise paint over the tiles. */
    position: relative;
    z-index: 1;
    justify-self: center;
    width: min(100%, 11rem);
    min-height: 3.4rem;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.7rem 0.9rem;
    border: 2px solid color-mix(in srgb, rgb(var(--join-ink)) 22%, var(--join-surface));
    border-radius: 14px;
    background: var(--join-surface);
    cursor: pointer;
    text-align: center;
    -webkit-tap-highlight-color: transparent;
    transition:
        background-color 0.2s ease,
        border-color 0.2s ease;
}

.join-step__label {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    line-height: 1.25;
    color: #5d5854;
    transition: color 0.2s ease;
}

/* Scoped off the active tile, which is (0,2,0) here and would otherwise lose
   its own border colour to the hover rule. */
.join-step:not(.join-step--active):hover,
.join-step:not(.join-step--active):focus-visible {
    border-color: color-mix(in srgb, rgb(var(--join-ink)) 45%, var(--join-surface));
}

.join-step:hover .join-step__label,
.join-step:focus-visible .join-step__label,
.join-step--done .join-step__label {
    color: rgb(var(--join-ink));
}

.join-step--done {
    border-color: color-mix(in srgb, rgb(var(--join-deep)) 50%, var(--join-surface));
}

/* The selected tile is a filled tile with a darker edge — the border keeps its
   own solid colour rather than going transparent and letting the gradient's
   pale corner run out to the edge, which read as a bezel. */
.join-step--active {
    /* Colour and gradient separately: the `background` shorthand would reset
       background-color to transparent and leave the fill resting entirely on
       the gradient. */
    background-color: rgb(var(--join-deep));
    background-image: linear-gradient(135deg, rgb(var(--join-accent)), rgb(var(--join-deep)));
    border-color: rgb(var(--join-deep));
}

.join-step--active .join-step__label,
.join-step--active:hover .join-step__label {
    color: #fff7f5;
}

.join-step:focus {
    outline: none;
}

.join-step:focus-visible {
    outline: 2px solid rgb(var(--join-ink));
    outline-offset: 3px;
}

/* ── Stage panel ── */
.join-stage {
    padding: 2.1rem 2.2rem 2.3rem;
    display: flex;
    flex-direction: column;
    gap: 2rem;
}

/* swapTabPanels hides the inactive stages with the `hidden` attribute, and the
   `display: flex` above outranks the UA rule that would act on it — without
   this every stage paints at once. */
.join-stage[hidden] {
    display: none;
}

.join-stage__eyebrow {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: rgba(var(--join-ink), 0.8);
}

.join-stage__heading {
    margin: 0.5rem 0 0.75rem;
    font-family: Georgia, "Times New Roman", serif;
    font-size: clamp(1.5rem, 2.2vw, 2.1rem);
    font-weight: 700;
    line-height: 1.15;
    color: #1a1a1a;
}

.join-stage__lede {
    max-width: 48rem;
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 1rem;
    line-height: 1.75;
    color: #4a4642;
}

.join-stage__lede > * + * {
    margin-top: 0.7rem;
}

/* Lists written as "- item" in the content module. Custom markers so the
   bullet takes the level's colour. */
.join-rich-list {
    list-style: none;
    padding-left: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.join-rich-list li {
    position: relative;
    padding-left: 1.15rem;
}

.join-rich-list li::before {
    content: "";
    position: absolute;
    left: 0.1rem;
    /* Centred on the first line's cap height rather than the whole item, so a
       bullet that wraps to two lines keeps its marker beside the first. */
    top: calc(0.875rem - 0.185rem);
    width: 0.37rem;
    height: 0.37rem;
    border-radius: 999px;
    background: rgba(var(--join-accent), 0.85);
}

/* An author who wrote their own marker — "✅ …" — keeps it. The dot above is
   only the default for a plain "- " list. */
.join-rich-list li[data-marker] {
    padding-left: 1.75rem;
}

.join-rich-list li[data-marker]::before {
    content: attr(data-marker);
    top: 0;
    left: 0;
    width: auto;
    height: auto;
    border-radius: 0;
    background: none;
    font-size: 0.92em;
    line-height: inherit;
}

/* ── Blocks ── */
.join-block__title {
    margin-bottom: 0.55rem;
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: rgb(var(--join-ink));
}

.join-block__note {
    max-width: 44rem;
    margin-bottom: 1rem;
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 0.85rem;
    line-height: 1.65;
    color: #6b6663;
}

.join-block__title + .join-routes,
.join-block__title + .join-steps,
.join-block__title + .join-faq,
.join-block__title + .join-filters__bar {
    margin-top: 0.9rem;
}

.join-link {
    color: rgb(var(--join-ink));
    font-weight: 600;
    text-decoration: none;
    border-bottom: 1px solid rgba(var(--join-ink), 0.28);
}

.join-link:hover {
    border-bottom-color: rgba(var(--join-ink), 0.8);
}

/* ── Routes ── */
.join-routes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
    gap: 0.9rem;
    align-items: start;
}

.join-route {
    /* Anchors .join-route__stars, and the filter takes rows out with [hidden]. */
    position: relative;
    padding: 1.2rem 1.3rem 1.3rem;
    border-radius: 18px;
    background: rgba(255, 255, 255, 0.6);
    border: 1px solid rgba(17, 17, 17, 0.07);
    transition:
        transform 0.18s ease,
        box-shadow 0.18s ease,
        border-color 0.18s ease;
}

.join-route[hidden] {
    display: none;
}

.join-route:hover {
    transform: translateY(-2px);
    border-color: rgba(var(--join-ink), 0.18);
    box-shadow: 0 16px 34px rgba(17, 17, 17, 0.08);
}

/* Clears the stars so a long meta line does not run under them. */
.join-route--featured .join-route__meta,
.join-route--featured .join-route__name {
    padding-right: 3.4rem;
}

/* ── Featured cards ──
   Lifted out of the grid's uniformity by weight rather than size: keeping the
   footprint identical means the grid stays on its rhythm however many are
   flagged, and the accent does the pointing. */
.join-route--featured {
    background: linear-gradient(180deg, rgba(var(--join-accent), 0.1), rgba(255, 255, 255, 0.66) 60%);
    border-color: rgba(var(--join-accent), 0.42);
    box-shadow: 0 12px 30px rgba(var(--join-ink), 0.08);
}

.join-route--featured:hover {
    border-color: rgba(var(--join-ink), 0.35);
    box-shadow: 0 18px 38px rgba(var(--join-ink), 0.14);
}

/* Three stars in the corner rather than a labelled pill: it marks the card
   without taking a line of its own or competing with the name. Absolute, so it
   costs the card no height and every card in the row stays aligned. */
.join-route__stars {
    position: absolute;
    top: 0.95rem;
    right: 1.1rem;
    font-size: 0.62rem;
    letter-spacing: 0.1em;
    line-height: 1;
    color: rgba(var(--join-accent), 0.95);
}

.join-route__meta {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 0.64rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: rgba(var(--join-ink), 0.75);
}

.join-route__name {
    margin: 0.45rem 0 0.5rem;
    font-family: Georgia, "Times New Roman", serif;
    font-size: 1.12rem;
    line-height: 1.25;
    color: #181818;
}

.join-route__blurb {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 0.88rem;
    line-height: 1.7;
    color: #5b5652;
}

.join-route__highlights {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin: 0.85rem 0 0;
    padding: 0;
    list-style: none;
}

.join-route__highlights li {
    padding: 0.22rem 0.6rem;
    border-radius: 999px;
    background: rgba(var(--join-accent), 0.09);
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 0.66rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    color: rgb(var(--join-ink));
}

.join-route__links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1rem;
    margin-top: 0.95rem;
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 0.8rem;
}

.join-route__links .join-link::after {
    content: " ↗";
    font-size: 0.75em;
    opacity: 0.6;
}

.join-route__links .join-link[href^="#"]::after,
.join-route__links .join-link[href^="mailto:"]::after {
    content: " →";
}

/* ── Eligibility filter ──
   Above the card grid on any level whose items carry tags. */
.join-filters__bar {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.6rem 1rem;
    margin-bottom: 0.9rem;
}

.join-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.join-filter {
    padding: 0.32rem 0.8rem;
    border-radius: 999px;
    border: 1px solid rgba(var(--join-ink), 0.2);
    background: rgba(255, 255, 255, 0.6);
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    color: rgba(var(--join-ink), 0.8);
    cursor: pointer;
    transition:
        background-color 0.16s ease,
        border-color 0.16s ease,
        color 0.16s ease;
}

.join-filter:hover {
    border-color: rgba(var(--join-ink), 0.42);
    color: rgb(var(--join-ink));
}

.join-filter--active {
    background: linear-gradient(135deg, rgba(var(--join-accent), 0.92), rgba(var(--join-deep), 0.95));
    border-color: transparent;
    color: #fff7f5;
}

.join-filters__count {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: rgba(60, 57, 54, 0.45);
}

/* ── Numbered steps ── */
.join-steps {
    counter-reset: join-step;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    gap: 0.9rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.join-step-item {
    counter-increment: join-step;
    position: relative;
    padding: 1.15rem 1.25rem 1.25rem;
    border-radius: 18px;
    background: rgba(255, 255, 255, 0.45);
    border: 1px solid rgba(17, 17, 17, 0.06);
    border-top: 2px solid rgba(var(--join-ink), 0.3);
}

.join-step-item::before {
    content: counter(join-step);
    display: block;
    margin-bottom: 0.5rem;
    font-family: Georgia, "Times New Roman", serif;
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1;
    color: rgba(var(--join-ink), 0.28);
}

.join-step-item__title {
    margin-bottom: 0.45rem;
    font-family: Georgia, "Times New Roman", serif;
    font-size: 1.05rem;
    line-height: 1.25;
    color: #181818;
}

.join-step-item__text {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 0.86rem;
    line-height: 1.7;
    color: #5b5652;
}

/* ── FAQ / advice accordions ── */
.join-faq {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.join-faq__item {
    border-radius: 16px;
    background: rgba(255, 255, 255, 0.5);
    border: 1px solid rgba(17, 17, 17, 0.06);
    overflow: hidden;
}

.join-faq__item[open] {
    background: rgba(255, 255, 255, 0.72);
    border-color: rgba(var(--join-ink), 0.16);
}

.join-faq__question {
    position: relative;
    display: block;
    padding: 0.95rem 3.2rem 0.95rem 1.2rem;
    cursor: pointer;
    list-style: none;
    font-family: Georgia, "Times New Roman", serif;
    font-size: 1rem;
    line-height: 1.35;
    color: #262320;
}

.join-faq__question::-webkit-details-marker {
    display: none;
}

.join-faq__question::after {
    content: "+";
    position: absolute;
    top: 50%;
    right: 1rem;
    width: 1.7rem;
    height: 1.7rem;
    margin-top: -0.85rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: rgba(var(--join-accent), 0.1);
    color: rgb(var(--join-ink));
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 1.2rem;
    line-height: 1;
    transition: background-color 0.18s ease;
}

.join-faq__item[open] .join-faq__question::after {
    content: "−";
    background: rgba(var(--join-accent), 0.18);
}

.join-faq__answer {
    padding: 0 1.2rem 1.2rem;
}

.join-faq__answer p {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 0.88rem;
    line-height: 1.75;
    color: #5b5652;
}

.join-faq__answer p + p {
    margin-top: 0.7rem;
}

/* ── Callout ── */
.join-note {
    padding: 1.05rem 1.3rem 1.15rem;
    border-radius: 16px;
    border: 1px solid rgba(var(--join-ink), 0.14);
    border-left: 3px solid rgba(var(--join-accent), 0.55);
    background: rgba(var(--join-accent), 0.07);
}

.join-note--warn {
    border-left-color: rgba(220, 140, 40, 0.7);
    background: rgba(255, 250, 238, 0.65);
}

.join-note__title {
    margin-bottom: 0.35rem;
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 0.76rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: rgb(var(--join-ink));
}

.join-note__text {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 0.88rem;
    line-height: 1.7;
    color: #5b5652;
}

.join-note__text > * + * {
    margin-top: 0.7rem;
}

/* Emphasis written as **strong** in the content module. Weight alone reads as
   an accident at this size, so it takes the level's ink as well. */
.join-note__text strong,
.join-stage__lede strong,
.join-route__blurb strong {
    font-weight: 600;
    color: rgb(var(--join-ink));
}

/* ── Outro ── */
.join-outro {
    padding: 1.8rem 2.2rem 1.9rem;
}

.join-outro__kicker {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: rgba(var(--join-ink), 0.8);
}

.join-outro__title {
    margin: 0.45rem 0 0.6rem;
    font-family: Georgia, "Times New Roman", serif;
    font-size: clamp(1.25rem, 1.8vw, 1.7rem);
    line-height: 1.2;
    color: #1a1a1a;
}

.join-outro__text {
    max-width: 44rem;
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 0.93rem;
    line-height: 1.75;
    color: #4a4642;
}

.join-outro__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.7rem;
    margin-top: 1.2rem;
}

