/**
 * Forme · page frame and chrome (design spec §5, contract §2.2, §2.4, §2.10, §2.11).
 *
 *  1. Container, shell and skip link
 *  2. Rows: 12-column grid, dead tracks, row rhythm
 *  3. Full-bleed bands (welcome, the board, the accent band)
 *  4. Home and app mode
 *  5. Tonight strip (library top bar + the community "strip" block)
 *  6. Header: brand, actions, search field, account
 *  7. Navigation: inline from 56.25rem (900px), drawer below
 *  8. Footer: columns, stats, bottom bar, scheme toggle, languages
 *  9. Megamenu skin (single-class selectors over the library skeleton)
 *
 * Markup is the library's (ChromeRenderer, LayoutRenderer) plus the kit's module layouts; no
 * rule here depends on Bootstrap, so BS-off app pages keep the same chrome. Island safety: every
 * selector is under a template class; nothing styles bare elements (contract §2.4).
 *
 * @copyright   Copyright (C) 2026 BulaSikku Technologies Private Limited. All rights reserved.
 * @license     GNU General Public License version 2 or later
 */

/* ==========================================================================
   1. Container, shell and skip link
   ========================================================================== */

.ts-container {
    inline-size: min(100%, var(--page-max));
    margin-inline: auto;
    padding-inline: var(--page-gutter);
}

.ts-shell {
    display: flow-root;
}

.ts-skip-link {
    position: absolute;
    inset-block-start: 0.75rem;
    inset-inline-start: 0.75rem;
    z-index: calc(var(--ts-z-toast) + 1);
    display: inline-flex;
    align-items: center;
    min-block-size: 2.75rem;
    padding: 0 1.25rem;
    border-radius: var(--ec-btn-radius);
    background-color: var(--ec-accent);
    color: var(--ec-accent-fg);
    font-weight: 700;
    text-decoration: none;
    transform: translateY(-200%);
}

.ts-skip-link:focus,
.ts-skip-link:focus-visible {
    outline-color: var(--fm-ink);
    transform: none;
}

/* The logo mark: a window of four panes with the top-right pane lit (design spec §4.6). Drawn
   with a mask so it follows the ink (--ec-fg) and the preset accent in both schemes. */
.ts-brand__text::before,
.ts-header__nav::before,
.fm-error__mark {
    content: "";
    flex: none;
    inline-size: var(--fm-mark, 2rem);
    block-size: var(--fm-mark, 2rem);
    background:
        linear-gradient(var(--ec-accent), var(--ec-accent))
        calc(var(--fm-mark, 2rem) * 17 / 32) calc(var(--fm-mark, 2rem) * 3 / 32) /
        calc(var(--fm-mark, 2rem) * 12 / 32) calc(var(--fm-mark, 2rem) * 12 / 32) no-repeat,
        var(--ec-fg);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpath d='M17 3h9a3 3 0 0 1 3 3v9H17z'/%3E%3Cpath d='M3 2h23a4 4 0 0 1 4 4v20a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4V3a1 1 0 0 1 1-1z' fill='none' stroke='%23000' stroke-width='2'/%3E%3Cpath d='M16 2v28M2 16h28' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpath d='M17 3h9a3 3 0 0 1 3 3v9H17z'/%3E%3Cpath d='M3 2h23a4 4 0 0 1 4 4v20a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4V3a1 1 0 0 1 1-1z' fill='none' stroke='%23000' stroke-width='2'/%3E%3Cpath d='M16 2v28M2 16h28' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
}

/* ==========================================================================
   2. Rows: 12-column grid, dead tracks, row rhythm
   ========================================================================== */

.ts-row {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--ec-grid-gap);
    row-gap: var(--fm-s-10);
    align-items: start;
    padding-block: 0 var(--ec-sect-y);
}

.ts-col {
    grid-column: 1 / -1;
    min-inline-size: 0;
}

@media (min-width: 48rem) {
    .ts-span-1 { grid-column: span 1; }
    .ts-span-2 { grid-column: span 2; }
    .ts-span-3 { grid-column: span 3; }
    .ts-span-4 { grid-column: span 4; }
    .ts-span-5 { grid-column: span 5; }
    .ts-span-6 { grid-column: span 6; }
    .ts-span-7 { grid-column: span 7; }
    .ts-span-8 { grid-column: span 8; }
    .ts-span-9 { grid-column: span 9; }
    .ts-span-10 { grid-column: span 10; }
    .ts-span-11 { grid-column: span 11; }
    .ts-span-12 { grid-column: span 12; }
}

/* A module that prints nothing still counts for the library, so its column exists but is
   empty: hide it, let a lone column span the row, and drop a row with nothing to show. */
.ts-row > .ts-col:empty {
    display: none;
}

.ts-row:not(:has(> .ts-col:not(:empty) ~ .ts-col:not(:empty))) > .ts-col:not(:empty) {
    grid-column: 1 / -1;
}

.ts-row:not(:has(> .ts-col:not(:empty))) {
    display: none;
}

/* The hero opens the page under the header; later sections keep the section rhythm. */
.ts-row[data-ts-row="hero"],
.ts-row:has(> .ts-pos-hero) {
    padding-block-start: clamp(2rem, 0.83rem + 4.8vw, 4rem);
}

/* Inner pages: breathing room above the component; the home decides for itself (4). */
.ts-row[data-ts-row="content"] {
    padding-block-start: clamp(1.5rem, 0.93rem + 2.29vw, 3rem);
}

/* ==========================================================================
   3. Full-bleed bands (contract §2.4.7): the row paints its tone past the container with a
      filled border image outset by 100vmax sideways. Like the spread-shadow technique it is
      ink overflow only (no scrollbar, no 100vw), and it paints inside and outside the row in
      one pass, so a band that starts on a fractional pixel shows no seam at the container edge.
   ========================================================================== */

.ts-row[data-ts-row="below-top"],
.ts-row[data-ts-row="band"],
.ts-row[data-ts-row="cta"],
.ts-row:has(> .ts-pos-bottom-a),
.ts-row:has(> .ts-pos-footer-top) {
    border-image: linear-gradient(var(--fm-band-tone), var(--fm-band-tone)) fill 0 / 0 / 0 100vmax;
}

/* The same tone as a real background on the columns (inside the painted band, so invisible):
   contrast checkers and assistive tools read background-color, not border images. */
.ts-row[data-ts-row="below-top"] > .ts-col,
.ts-row[data-ts-row="band"] > .ts-col,
.ts-row[data-ts-row="cta"] > .ts-col,
.ts-row:has(> .ts-pos-bottom-a) > .ts-col,
.ts-row:has(> .ts-pos-footer-top) > .ts-col {
    background-color: var(--fm-band-tone);
}

/* Welcome back (members): a surface strip straight under the header. */
.ts-row[data-ts-row="below-top"] {
    --fm-band-tone: var(--ec-surface);
    padding-block: 0;
}

/* The board: the surface band that holds the leaderboard and "Your turn". */
.ts-row[data-ts-row="band"],
.ts-row:has(> .ts-pos-bottom-a) {
    --fm-band-tone: var(--ec-surface);
    padding-block: clamp(2.5rem, 1.57rem + 3.81vw, 5rem);
}

.ts-row[data-ts-row="band"] + .ts-row,
.ts-row:has(> .ts-pos-bottom-a) + .ts-row {
    padding-block-start: var(--ec-sect-y);
}

/* The accent band: one per page, scheme-invariant, ink on accent. */
.ts-row[data-ts-row="cta"],
.ts-row:has(> .ts-pos-footer-top) {
    --fm-band-tone: var(--fm-band);
    --ts-focus: var(--fm-ink);
    padding-block: clamp(3rem, 1.24rem + 5.36vw, 6rem);
    color: var(--fm-band-fg);
}

/* The band is the page's last word before the footer. */
.ts-shell:has(> .ts-row[data-ts-row="cta"]:last-child),
.ts-shell:has(> .ts-row:last-child > .ts-pos-footer-top),
.ts-shell:has(> .ts-main:last-child > .ts-row[data-ts-row="cta"]:last-child) {
    padding-block-end: 0;
}

/* ==========================================================================
   4. Home and app mode
   ========================================================================== */

/* Forme's home is built from rows; its featured view is empty, so the content row keeps
   only the (live) system message container. Collapse it until a message arrives; the home
   script (partials/body-end.php) then moves <main> around the rows, so a message opens the
   page right under the header. */
.ts-home .ts-row[data-ts-row="content"]:not(:has(.ts-main > :not(#system-message-container))):not(:has(#system-message-container > *)):not(:has(> .ts-pos-sidebar-left:not(:empty), > .ts-pos-sidebar-right:not(:empty))) {
    display: none;
}

.fm-main--rows > #system-message-container:has(> *) {
    padding-block-start: clamp(1.5rem, 0.93rem + 2.29vw, 3rem);
}

/* Breadcrumbs row (inner pages): the trail over the page head; the home has none. */
.ts-row[data-ts-row="crumbs"] {
    padding-block: clamp(1rem, 0.6rem + 1.6vw, 2rem) 0;
}

.ts-row[data-ts-row="crumbs"] + .ts-row[data-ts-row="content"] {
    padding-block-start: clamp(1rem, 0.6rem + 1.6vw, 2rem);
}

.ts-home .ts-row[data-ts-row="crumbs"] {
    display: none;
}

/* App mode (contract §2.2): the extension owns the page. Static header, full-width content,
   sidebars below the app, no sticky offset. */
.ts-app {
    --ts-sticky-offset: 0px;
}

.ts-app .ts-header.is-sticky {
    position: relative;
    z-index: auto;
}

/* ...but over the app's sticky bar while its search band or a menu is open. */
.ts-app .ts-header:has([data-ts-search-band][data-open], details[open]) {
    z-index: var(--ts-z-header);
}

.ts-app .ts-row[data-ts-row="content"] > .ts-col {
    grid-column: 1 / -1;
}

.ts-app .ts-row[data-ts-row="content"] > .ts-pos-main {
    order: -1;
}

.ts-app .ts-main {
    max-inline-size: none;
}

/* ==========================================================================
   5. Tonight strip: the library top bar in the night scope (tokens.css), holding the
      community "strip" block (Live pill, posts today, the next events, All events).
   ========================================================================== */

.ts-topbar {
    background-color: var(--fm-strip-bg);
    color: var(--ec-fg);
    font-size: 1rem;
    line-height: 1.25;
}

.ts-topbar__inner {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    min-block-size: 2.5rem;
}

/* A top bar whose only module printed nothing (no strip data yet) takes no room. */
.ts-topbar:not(:has(.ts-topbar__text, .ts-topbar__side--start > *, .ts-topbar__modules > *, .ts-social-links)) {
    display: none;
}

.ts-topbar__side--start:empty,
.ts-topbar__inner > span:empty {
    display: none;
}

.ts-topbar__side--end {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    justify-content: flex-end;
    min-inline-size: 0;
}

.ts-topbar__modules {
    flex: 1 1 auto;
    min-inline-size: 0;
}

.ts-topbar__text {
    margin: 0;
    padding-block: 0.625rem;
    color: var(--ec-fg);
}

/* The strip is a desktop marquee (design spec §5.1): phones start at the header. */
@media (width < 48rem) {
    .ts-topbar:has(.ts-strip) {
        display: none;
    }
}

.ts-strip {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    min-inline-size: 0;
    white-space: nowrap;
    container-type: inline-size;
}

.ts-strip__week {
    display: none;
}

.ts-topbar .ts-strip__live,
.ts-strip__live.ts-tag {
    display: inline-flex;
    flex: none;
    align-items: center;
    block-size: 1.375rem;
    padding: 0 0.5rem;
    border-radius: var(--fm-r-pill-live);
    background-color: var(--fm-live);
    color: var(--fm-live-fg);
    font-size: var(--fm-t-tag);
    font-weight: 700;
    line-height: 1;
    text-decoration: none;
}

/* Items that do not fit wrap onto a second line that is clipped away, so a fact is shown
   whole or not at all (also with user text spacing, WCAG 1.4.12). */
.ts-strip__items {
    display: flex;
    flex: 1 1 auto;
    flex-wrap: wrap;
    align-items: center;
    gap: 3rem 1.25rem;
    min-inline-size: 0;
    max-block-size: 2.75rem;
    margin: -0.125rem 0;
    padding: 0;
    overflow: clip;
    list-style: none;
}

.ts-strip__item {
    display: flex;
    flex: none;
    align-items: center;
    gap: 1.25rem;
}

/* 1 x 16 rules between the facts. */
.ts-strip__item + .ts-strip__item::before {
    content: "";
    inline-size: 1px;
    block-size: 1rem;
    background-color: var(--ec-border);
}

/* 44px targets inside the 40px bar: the hit area reaches past the text, the bar keeps its height. */
.ts-strip__link {
    display: inline-flex;
    align-items: baseline;
    gap: 0.5rem;
    padding-block: 0.75rem;
    color: inherit;
    text-decoration: none;
}

.ts-strip__time {
    color: var(--ec-fg-2);
}

.ts-strip__strong {
    font-weight: 700;
}

.ts-strip__item--event .ts-strip__strong {
    font-weight: 400;
}

.ts-strip__item--metric .ts-strip__text {
    margin-inline-start: -0.25rem;
}

.ts-strip__item--event .ts-strip__text {
    margin-inline-start: -0.5rem;
}

.ts-strip__item--event .ts-strip__text::before {
    content: ", ";
}

.ts-strip__more {
    display: inline-flex;
    flex: none;
    align-items: center;
    gap: 0.375rem;
    margin-block: -0.75rem;
    margin-inline-start: auto;
    padding-block: 0.75rem;
    color: var(--fm-accent-ink);
    font-weight: 700;
    text-decoration: none;
}

.ts-strip__more svg {
    inline-size: 1rem;
    block-size: 1rem;
    stroke-width: 1.75;
}

@media (hover: hover) and (pointer: fine) {
    .ts-strip__link:hover .ts-strip__strong,
    .ts-strip__more:hover .ts-more__label {
        text-decoration: underline 2px;
        text-underline-offset: 4px;
    }

    .ts-strip__more:hover {
        color: var(--fm-accent-ink-hover);
    }
}

/* Too narrow for every fact: later events drop out whole (never wrap). */
@container (max-width: 56rem) {
    .ts-strip__item--event ~ .ts-strip__item--event {
        display: none;
    }
}

@container (max-width: 40rem) {
    .ts-strip__item--event {
        display: none;
    }
}

/* ==========================================================================
   6. Header: brand, actions, search field, account
   ========================================================================== */

.ts-header {
    --fm-mark: 1.75rem;
    background-color: var(--ec-bg);
    color: var(--ec-fg);
}

.ts-header.is-sticky {
    position: sticky;
    inset-block-start: 0;
    z-index: var(--ts-z-header);
}

/* "Stuck" rule: a hairline appears once the page scrolls under the header (progressive
   enhancement; the background stays opaque, no blur). */
@supports (animation-timeline: scroll()) {
    .ts-header.is-sticky {
        animation: forme-header-stuck linear both;
        animation-range: 0 1px;
        animation-timeline: scroll(root block);
    }

    .ts-app .ts-header.is-sticky {
        animation: none;
    }
}

@keyframes forme-header-stuck {
    from { box-shadow: 0 1px 0 transparent; }
    to { box-shadow: 0 1px 0 var(--ec-border); }
}

.ts-header__inner {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-block-size: 3.5rem;
    padding-inline-end: max(0.5rem, calc(var(--page-gutter) - 0.5rem));
}

.ts-header svg {
    stroke-width: 1.75;
}

/* Brand: mark + wordmark, a 44px link. */
.ts-brand {
    display: inline-flex;
    flex: none;
    align-items: center;
    min-block-size: 2.75rem;
    color: var(--ec-fg);
    text-decoration: none;
}

.ts-brand__text {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-family: var(--ec-font-display);
    font-size: var(--fm-t-wordmark);
    font-stretch: var(--fm-disp-stretch);
    font-weight: var(--fm-num-weight);
    letter-spacing: -0.01em;
    line-height: 1.25;
    white-space: nowrap;
}

/* Safety net for long site names in a narrow header: the name clips before the actions
   (phones and tablets only; from 64rem the wordmark keeps its full width, text spacing too). */
@media (min-width: 64rem) {
    .ts-header .ts-brand.ts-brand {
        flex-shrink: 0;
    }
}

.ts-header .ts-brand {
    flex: 0 1 auto;
    min-inline-size: 0;
}

.ts-header .ts-brand__text {
    min-inline-size: 0;
    overflow: clip;
}

/* The smallest phones keep the mark and the four action buttons; the name stays readable to
   assistive technology. */
@media (width < 23.75rem) {
    .ts-header .ts-brand__text {
        font-size: 0;
    }
}

.ts-brand__logo {
    display: block;
    inline-size: auto;
    block-size: var(--fm-mark);
    max-inline-size: 12rem;
}

.ts-brand__logo--dark,
[data-color-scheme="dark"] .ts-brand__logo--light {
    display: none;
}

[data-color-scheme="dark"] .ts-brand__logo--dark {
    display: block;
}

/* Actions: the header-actions position (search, account) then the menu toggle. */
.ts-header__actions {
    display: flex;
    flex: none;
    align-items: center;
    gap: 0.125rem;
    margin-inline-start: auto;
}

.ts-header__modules {
    display: flex;
    align-items: center;
    gap: 0.125rem;
}

/* Icon buttons (library actions, search toggle, bell): 44 x 44, radius 10, transparent. */
.ts-header .ts-action,
.ts-account__bell {
    position: relative;
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    inline-size: 2.75rem;
    block-size: 2.75rem;
    padding: 0;
    border: 0;
    border-radius: var(--ec-btn-radius);
    background: transparent;
    color: var(--ec-fg);
    font: inherit;
    cursor: pointer;
    transition: background-color var(--ec-dur-1) var(--ec-ease), color var(--ec-dur-1) var(--ec-ease);
}

.ts-header .ts-action svg,
.ts-account__bell svg {
    inline-size: 1.375rem;
    block-size: 1.375rem;
}

.ts-nav-toggle svg {
    inline-size: 1.5rem;
    block-size: 1.5rem;
}

.ts-header .ts-nav-toggle--labelled {
    inline-size: auto;
    gap: 0.5rem;
    padding-inline: 0.75rem;
    font-weight: 700;
}

@media (hover: hover) and (pointer: fine) {
    .ts-header .ts-action:hover,
    .ts-account__bell:hover {
        background-color: var(--ec-surface);
    }
}

.ts-header .ts-action:active,
.ts-account__bell:active,
.ts-header .ts-action[aria-expanded="true"] {
    background-color: var(--ec-surface-2);
}

/* Cart badge (EasyCommerce through the library). */
.ts-action__badge {
    position: absolute;
    inset-block-start: 0.25rem;
    inset-inline-end: 0.125rem;
    min-inline-size: 1.125rem;
    block-size: 1.125rem;
    padding: 0 0.25rem;
    border-radius: 0.5625rem;
    background-color: var(--ec-accent);
    color: var(--ec-accent-fg);
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1.125rem;
    text-align: center;
}

/* ---- Search: an inline 232px field on wide screens, a band under the header below that
        (kit layout "header": toggle + panel; template.js keeps the panel visible whenever
        the toggle is not rendered). ---- */

.ts-search--header .ts-search__panel {
    position: absolute;
    inset-block-start: 100%;
    inset-inline: 0;
    z-index: 1;
    padding: 0.5rem max(var(--page-gutter), calc((100% - var(--page-max)) / 2 + var(--page-gutter)));
    border-block-end: 1px solid var(--ec-border);
    background-color: var(--ec-bg);
    box-shadow: var(--fm-overlay-shadow);
}

.ts-search__form {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
}

.ts-search__field {
    position: relative;
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    min-inline-size: 0;
}

/* Smart Search autosuggest wraps the input in div.awesomplete: that wrapper is the flex item. */
.ts-search__field > .awesomplete {
    display: block;
    flex: 1 1 auto;
    min-inline-size: 0;
}

.ts-search__icon {
    position: absolute;
    inset-inline-start: 0.875rem;
    z-index: 1;
    display: inline-flex;
    color: var(--ec-fg-2);
    pointer-events: none;
}

.ts-search__icon svg {
    inline-size: 1.125rem;
    block-size: 1.125rem;
    stroke-width: 1.75;
}

.ts-search__field .ts-search__input {
    inline-size: 100%;
    min-inline-size: 0;
    block-size: 3rem;
    min-block-size: 0;
    margin: 0;
    padding: 0 0.875rem 0 2.5rem;
    border: 1px solid var(--fm-control);
    border-radius: var(--ec-btn-radius);
    background-color: var(--ec-surface);
    box-shadow: none;
    color: var(--ec-fg);
    font: inherit;
    font-size: 1rem;
    line-height: 1.25;
    appearance: none;
    transition: border-color var(--ec-dur-1) var(--ec-ease);
}

.ts-search__field .ts-search__input::placeholder {
    color: var(--ec-fg-2);
    opacity: 1;
}

.ts-search__field .ts-search__input:focus,
.ts-search__field .ts-search__input:focus-visible {
    border-color: var(--fm-focus);
    outline: var(--ts-focus-width, 2px) solid var(--ts-focus);
    outline-offset: 2px;
    box-shadow: none;
}

@media (hover: hover) and (pointer: fine) {
    .ts-search__field .ts-search__input:hover:not(:focus) {
        border-color: var(--ec-fg-2);
    }
}

.ts-search--header .ts-search__submit {
    flex: none;
}

/* CjForum and Sociable keep their own search field: there the header's site search stays the icon
   button and band at every width (the kit hid it), so the header actions keep their place. */
body:is(.ts-app--cjforum, .ts-app--sociable) .ts-header__modules .ts-search--header {
    display: block;
}

@media (min-width: 85rem) {
    :where(body:not(.ts-app--cjforum, .ts-app--sociable)) .ts-search--header .ts-search__toggle,
    :where(body:not(.ts-app--cjforum, .ts-app--sociable)) .ts-search--header .ts-search__close,
    :where(body:not(.ts-app--cjforum, .ts-app--sociable)) .ts-search--header .ts-search__submit {
        display: none;
    }

    :where(body:not(.ts-app--cjforum, .ts-app--sociable)) .ts-search--header .ts-search__panel {
        position: static;
        padding: 0;
        border: 0;
        background: none;
        box-shadow: none;
    }

    :where(body:not(.ts-app--cjforum, .ts-app--sociable)) .ts-search--header .ts-search__field .ts-search__input {
        inline-size: 14.5rem;
        block-size: 2.75rem;
    }

    .ts-header__modules {
        gap: 0.75rem;
    }
}

/* ---- Account (community "account" block): guests get Sign in + Join, members the primary
        action, the bell and the avatar menu (design spec §5.2, §5.3). ---- */

.ts-header__modules .ts-account {
    display: flex;
    align-items: center;
    gap: 0.125rem;
}

.ts-header__modules .ts-account__login {
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-inline-size: 2.75rem;
    block-size: 2.75rem;
    padding: 0 0.75rem;
    border-radius: var(--ec-btn-radius);
    color: var(--ec-fg);
    font-size: 1.0625rem;
    font-weight: 700;
    text-decoration: none;
}

.ts-header__modules .ts-account__login svg {
    flex: none;
    inline-size: 1.375rem;
    block-size: 1.375rem;
}

.ts-header__modules .ts-account__join,
.ts-header__modules .ts-account__primary {
    flex: none;
}

@media (hover: hover) and (pointer: fine) {
    .ts-header__modules .ts-account__login:hover span {
        text-decoration: underline 2px;
        text-underline-offset: 4px;
    }
}

/* Phones and tablets: icons only; Join and the primary action live in the drawer and hero. */
@media (width < 64rem) {
    .ts-header__modules .ts-account__login {
        padding: 0;
    }

    .ts-header__modules .ts-account__login span,
    .ts-header__modules .ts-account__name,
    .ts-header__modules .ts-account__points {
        position: absolute;
        inline-size: 1px;
        block-size: 1px;
        margin: -1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }

    .ts-header__modules .ts-account__join,
    .ts-header__modules .ts-account__primary {
        display: none;
    }
}

/* The member's primary action needs the room of a wide header (bell and avatar stay). */
@media (width < 75rem) {
    .ts-header__modules .ts-account__primary {
        display: none;
    }
}

@media (min-width: 64rem) {
    .ts-header__modules .ts-account {
        gap: 0.75rem;
    }

    .ts-header__modules .ts-account__login svg {
        display: none;
    }

    .ts-header__modules .ts-account__name,
    .ts-header__modules .ts-account__points {
        position: absolute;
        inline-size: 1px;
        block-size: 1px;
        margin: -1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }
}

/* Unread dot: 8px signal with a ground-coloured gap; the count itself is in the label. */
.ts-header__modules .ts-account__count {
    position: absolute;
    inset-block-start: 0.625rem;
    inset-inline-end: 0.6875rem;
    inline-size: 0.5rem;
    block-size: 0.5rem;
    overflow: hidden;
    border-radius: 50%;
    background-color: var(--fm-signal);
    box-shadow: 0 0 0 2px var(--ec-bg);
    color: transparent;
    font-size: 0;
}

/* Avatar menu: a native disclosure; the summary is a 44px button around a 30px avatar. */
.ts-header__modules .ts-account__menu {
    position: relative;
}

.ts-header__modules .ts-account__toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-inline-size: 2.75rem;
    block-size: 2.75rem;
    border-radius: var(--ec-btn-radius);
    color: var(--ec-fg);
    cursor: pointer;
    list-style: none;
}

.ts-header__modules .ts-account__toggle::-webkit-details-marker {
    display: none;
}

.ts-header__modules .ts-account__toggle > svg {
    display: none;
}

.ts-header__modules .ts-account__avatar {
    inline-size: 1.875rem;
    block-size: 1.875rem;
    font-size: 0.75rem;
}

.ts-header__modules .ts-account__panel {
    position: absolute;
    inset-block-start: calc(100% + 0.5rem);
    inset-inline-end: 0;
    z-index: var(--ts-z-dropdown);
    min-inline-size: 15rem;
    padding: 0.375rem;
    border: 1px solid var(--ec-border);
    border-radius: var(--ec-radius);
    border-start-end-radius: var(--fm-r-tail);
    background-color: var(--ec-surface);
    box-shadow: var(--fm-overlay-shadow);
}

.ts-account__links {
    margin: 0;
    padding: 0;
    list-style: none;
}

.ts-account__logout {
    margin: 0.375rem 0 0;
    padding-block-start: 0.375rem;
    border-block-start: 1px solid var(--ec-border);
}

.ts-account__item {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    inline-size: 100%;
    min-block-size: 2.75rem;
    padding: 0 0.875rem;
    border: 0;
    border-radius: 0.5rem;
    background: transparent;
    color: var(--ec-fg);
    font: inherit;
    font-size: 1.0625rem;
    line-height: 1.3;
    text-align: start;
    text-decoration: none;
    cursor: pointer;
}

.ts-account__item svg {
    inline-size: 1.125rem;
    block-size: 1.125rem;
    color: var(--ec-fg-2);
}

@media (hover: hover) and (pointer: fine) {
    .ts-account__item:hover,
    .ts-account__toggle:hover {
        background-color: var(--ec-surface-2);
    }
}

/* ==========================================================================
   7. Navigation: the library's #ts-nav is the inline menu from 56.25rem (900px, the
      library's megamenu breakpoint) and the off-canvas drawer below (template.js).
   ========================================================================== */

.ts-header__nav .mod-menu {
    display: flex;
    flex-wrap: wrap;
    gap: 0;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ts-header__nav .mod-menu li {
    position: relative;
    margin: 0;
}

.ts-header__nav .mod-menu a,
.ts-header__nav .mod-menu .nav-header,
.ts-header__nav .mod-menu .mod-menu__separator {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--ec-fg);
    text-decoration: none;
}

.ts-nav-close {
    display: none;
}

/* ---- Drawer (below 56.25rem) ---- */
@media (width < 56.25rem) {
    .ts-header .ts-header__nav {
        --fm-mark: 1.75rem;
        position: fixed;
        inset-block: 0;
        inset-inline-end: 0;
        z-index: calc(var(--ts-z-header) + 1);
        display: flex;
        flex-direction: column;
        gap: 1rem;
        inline-size: min(100%, 22.5rem);
        padding: 0 var(--page-gutter) 1.5rem;
        overflow-y: auto;
        overscroll-behavior: contain;
        border-inline-start: 1px solid var(--ec-border);
        background-color: var(--ec-bg);
        box-shadow: var(--fm-overlay-shadow);
        visibility: hidden;
        transform: translateX(100%);
        transition:
            transform var(--ec-dur-3) var(--ec-ease),
            visibility 0s linear var(--ec-dur-3);
    }

    [dir="rtl"] .ts-header .ts-header__nav {
        transform: translateX(-100%);
    }

    .ts-nav-open .ts-header .ts-header__nav {
        visibility: visible;
        transform: none;
        transition: transform var(--ec-dur-3) var(--ec-ease), visibility 0s linear 0s;
    }

    /* Top row: the mark (decorative) at the start, the close button at the end. */
    .ts-header__nav::before {
        position: absolute;
        inset-block-start: 0.875rem;
        inset-inline-start: var(--page-gutter);
    }

    .ts-nav-close {
        display: inline-flex;
        flex: none;
        align-items: center;
        justify-content: center;
        align-self: flex-end;
        inline-size: 2.75rem;
        block-size: 2.75rem;
        margin-block: 0.375rem 0;
        margin-inline-end: calc(var(--page-gutter) * -1 + 0.5rem);
        padding: 0;
        border: 0;
        border-radius: var(--ec-btn-radius);
        background: transparent;
        color: var(--ec-fg);
        font: inherit;
        cursor: pointer;
    }

    .ts-nav-close svg {
        inline-size: 1.5rem;
        block-size: 1.5rem;
    }

    .ts-header__nav .mod-menu {
        flex-direction: column;
        border-block-start: 1px solid var(--ec-border);
    }

    .ts-header__nav .mod-menu > li {
        border-block-end: 1px solid var(--ec-border);
    }

    .ts-header__nav .mod-menu > li > a,
    .ts-header__nav .mod-menu > li > .nav-header,
    .ts-header__nav .mod-menu > li > .mod-menu__separator {
        min-block-size: 3.5rem;
        padding-inline: 1rem;
        font-size: 1.25rem;
        font-weight: 700;
        line-height: 1.4;
    }

    .ts-header__nav .mod-menu > li.active > a,
    .ts-header__nav .mod-menu > li.current > a {
        box-shadow: inset 3px 0 0 var(--fm-signal);
        background-color: var(--fm-lit);
        color: var(--fm-lit-fg);
    }

    [dir="rtl"] .ts-header__nav .mod-menu > li.active > a,
    [dir="rtl"] .ts-header__nav .mod-menu > li.current > a {
        box-shadow: inset -3px 0 0 var(--fm-signal);
    }

    .ts-header__nav .mod-menu__sub {
        margin: 0 0 0.5rem;
        padding: 0 0 0 1rem;
        list-style: none;
    }

    .ts-header__nav .mod-menu__sub a {
        min-block-size: 2.75rem;
        padding-inline: 1rem;
        color: var(--ec-fg-2);
        font-size: 1.0625rem;
    }

    .ts-header__nav .mod-menu a:focus-visible {
        outline-offset: -2px;
    }

    /* Scrim: the header's own layer, so it sits under the drawer in both header modes. */
    .ts-header__inner::after {
        content: "";
        position: fixed;
        inset: 0;
        z-index: var(--ts-z-scrim);
        background-color: var(--ts-scrim);
        opacity: 0;
        pointer-events: none;
        transition: opacity var(--ec-dur-2) var(--ec-ease);
    }

    .ts-nav-open .ts-header__inner::after {
        opacity: 1;
        pointer-events: auto;
    }

    /* Drawer extras (offcanvas position): search, account, scheme and language. */
    .ts-header__offcanvas {
        display: flex;
        flex-direction: column;
        gap: 1.25rem;
        padding-block-start: 0.5rem;
    }

    .ts-search--drawer .ts-search__row {
        display: flex;
        gap: 0.5rem;
    }

    .ts-search--drawer .ts-search__submit {
        flex: none;
        min-block-size: 3rem;
    }

    /* Account block, drawer variant: Join + Sign in for guests; identity, links, sign out. */
    .ts-account--drawer {
        display: flex;
        flex-direction: column;
        gap: 0.75rem;
    }

    .ts-account--drawer .ts-account__actions {
        display: flex;
        flex-direction: column;
        gap: 0.75rem;
    }

    .ts-account--drawer .ts-button {
        inline-size: 100%;
        min-block-size: 3rem;
    }

    .ts-account__who {
        display: flex;
        align-items: center;
        gap: 0.75rem;
    }

    .ts-account__who .ts-account__avatar {
        flex: none;
        inline-size: 2.75rem;
        block-size: 2.75rem;
        font-size: 1rem;
    }

    .ts-account__identity {
        display: flex;
        flex-direction: column;
        margin: 0;
    }

    .ts-account--drawer .ts-account__name {
        color: var(--ec-fg);
        font-size: 1.0625rem;
        font-weight: 700;
        line-height: 1.25rem;
    }

    .ts-account--drawer .ts-account__points {
        color: var(--ec-fg-2);
        font-size: 0.9375rem;
        line-height: 1.25rem;
    }

    .ts-account--drawer .ts-account__item {
        padding-inline: 0;
        border-radius: 0;
        border-block-end: 1px solid var(--ec-border);
    }

    .ts-account--drawer .ts-account__logout {
        margin: 0;
        padding: 0;
        border: 0;
    }

    .ts-account__item--notifications {
        justify-content: space-between;
    }
}

/* ---- Inline navigation (56.25rem and up) ---- */
@media (min-width: 56.25rem) {
    .ts-header {
        --fm-mark: 2rem;
    }

    .ts-header__inner {
        gap: clamp(1rem, 5.77vw - 2.19rem, 3rem);
        min-block-size: 4.5rem;
        padding-inline-end: var(--page-gutter);
    }

    .ts-brand__text {
        gap: 0.625rem;
    }

    .ts-header__nav::before {
        content: none;
    }

    .ts-header__nav .mod-menu {
        align-items: center;
        gap: clamp(1rem, 2.885vw - 0.59rem, 2rem);
    }

    .ts-header__nav .mod-menu > li > a,
    .ts-header__nav .mod-menu > li > .nav-header,
    .ts-header__nav .mod-menu > li > .mod-menu__separator {
        position: relative;
        min-block-size: 2.75rem;
        font-size: var(--fm-t-nav);
        font-weight: 500;
        line-height: 2.75rem;
        white-space: nowrap;
    }

    /* Current page: 700 with a 3px signal bar under the text (like the route tabs). */
    .ts-header__nav .mod-menu > li.current > a,
    .ts-header__nav .mod-menu > li.active > a {
        font-weight: 700;
    }

    .ts-header__nav .mod-menu > li.current > a::after,
    .ts-header__nav .mod-menu > li.active > a::after {
        content: "";
        position: absolute;
        inset-inline: 0;
        inset-block-end: 0;
        block-size: 3px;
        border-radius: var(--fm-r-bar);
        background-color: var(--fm-signal);
    }

    @media (hover: hover) and (pointer: fine) {
        .ts-header__nav .mod-menu > li > a:hover {
            text-decoration: underline 2px var(--ec-fg-2);
            text-underline-offset: 0.625rem;
        }

        .ts-header__nav .mod-menu > li.current > a:hover,
        .ts-header__nav .mod-menu > li.active > a:hover {
            text-decoration: none;
        }
    }

    /* Drop-downs: a surface bubble, 44px items. */
    .ts-header__nav .mod-menu__sub {
        position: absolute;
        inset-block-start: 100%;
        inset-inline-start: -0.875rem;
        z-index: var(--ts-z-dropdown);
        min-inline-size: 14rem;
        margin: 0;
        padding: 0.375rem;
        border: 1px solid var(--ec-border);
        border-radius: var(--ec-radius);
        border-start-start-radius: var(--fm-r-tail);
        background-color: var(--ec-surface);
        box-shadow: var(--fm-overlay-shadow);
        list-style: none;
        opacity: 0;
        visibility: hidden;
        transform: translateY(-0.25rem);
        transition:
            opacity var(--ec-dur-2) var(--ec-ease),
            transform var(--ec-dur-2) var(--ec-ease),
            visibility 0s linear var(--ec-dur-2);
    }

    .ts-header__nav .mod-menu li:hover > .mod-menu__sub,
    .ts-header__nav .mod-menu li:focus-within > .mod-menu__sub,
    .ts-header__nav .mod-menu__sub.show-menu {
        opacity: 1;
        visibility: visible;
        transform: none;
        transition-delay: 0s;
    }

    .ts-header__nav .mod-menu__sub a {
        min-block-size: 2.75rem;
        padding: 0 0.875rem;
        border-radius: 0.5rem;
        font-size: 1.0625rem;
        line-height: 1.3;
    }

    .ts-header__nav .mod-menu__sub li.current > a {
        color: var(--fm-accent-ink);
        font-weight: 700;
    }

    @media (hover: hover) and (pointer: fine) {
        .ts-header__nav .mod-menu__sub a:hover {
            background-color: var(--ec-surface-2);
        }
    }

    .ts-header .ts-nav-toggle,
    .ts-header__offcanvas {
        display: none;
    }
}

/* ==========================================================================
   8. Footer: brand column (blurb and stats), link columns, bottom bar (legal, scheme
      toggle, languages). The footer position (stats + tools) is placed into this grid.
   ========================================================================== */

.ts-footer {
    --fm-mark: 1.75rem;
    padding-block: 2rem 1.5rem;
    background-color: var(--fm-footer-bg);
    color: var(--ec-fg-2);
    font-size: 1rem;
    line-height: 1.375;
}

.ts-footer > .ts-container {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: 1rem;
    align-items: start;
}

.ts-footer__cols,
.ts-footer__main {
    display: contents;
}

/* Placement: brand (row 1), stats (row 2), link columns flow after them, then the bottom bar
   and the tools on late explicit rows; empty implicit rows between them have no height. */
.ts-footer__brand {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
    grid-column: 1 / -1;
    grid-row: 1;
    margin-block-end: 1.75rem;
}

.ts-footer__blurb {
    max-inline-size: 21.25rem;
    margin: 0;
    color: var(--ec-fg-2);
    text-wrap: balance;
}

@media (min-width: 48rem) {
    .ts-footer__blurb {
        text-wrap: wrap;
    }

    .ts-footer .ts-brand {
        min-block-size: var(--fm-mark);
    }
}

.ts-footer .ts-social-links {
    display: flex;
    gap: 0.25rem;
}

.ts-footer .ts-social {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 2.75rem;
    block-size: 2.75rem;
    border-radius: var(--ec-btn-radius);
    color: var(--ec-fg-2);
}

.ts-footer .ts-social svg {
    stroke-width: 1.75;
}

/* Link columns (Studio footer.columns and footer-1..4 modules). */
.ts-footer__col:not(.ts-footer__brand) {
    min-inline-size: 0;
    margin-block-end: 1.75rem;
}

.ts-footer__col :is(h2, h5),
.ts-footer__col .ts-module__title {
    margin: 0 0 0.25rem;
    color: var(--ec-fg);
    font-family: var(--ec-font-body);
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.375;
}

.ts-footer__col:not(.ts-footer__brand) ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

.ts-footer__col:not(.ts-footer__brand) li {
    margin: 0;
}

.ts-footer__col:not(.ts-footer__brand) a {
    display: flex;
    align-items: center;
    min-block-size: 2.75rem;
    color: var(--ec-fg-2);
    text-decoration: none;
}

/* Stats (community "pulse" block in the footer position) under the blurb. */
.ts-footer__main > .ts-module:has(.ts-pulse) {
    grid-column: 1 / -1;
    grid-row: 2;
    margin-block: -1rem 1.75rem;
}

.ts-footer .ts-pulse__presence {
    display: none;
}

.ts-footer .ts-pulse__list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 2rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ts-footer .ts-pulse__item,
.ts-footer .ts-pulse__link {
    display: flex;
    flex-direction: column;
    color: inherit;
    text-decoration: none;
}

.ts-footer .ts-pulse__value {
    color: var(--ec-fg);
    font-family: var(--ec-font-display);
    font-size: 1.375rem;
    font-stretch: var(--fm-disp-stretch);
    font-weight: var(--fm-num-weight);
    letter-spacing: -0.01em;
    line-height: 1.625rem;
}

.ts-footer .ts-pulse__label {
    color: var(--ec-fg-2);
    font-size: 0.9375rem;
    line-height: 1.125rem;
}

/* Bottom bar: copyright and legal; the tools (scheme, languages) follow on their own row
   on phones and share the bar from 48rem. */
.ts-footer__bottom {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0 1.25rem;
    grid-column: 1 / -1;
    grid-row: 20;
    padding-block-start: 1.25rem;
    border-block-start: 1px solid var(--ec-border);
    font-size: 0.9375rem;
    line-height: 1.25rem;
}

.ts-footer__copy {
    display: flex;
    align-items: center;
    min-block-size: 2.75rem;
    margin: 0;
}

.ts-footer__legal,
.ts-footer__pay {
    display: flex;
    flex-wrap: wrap;
    gap: 0 1.25rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ts-footer__legal a {
    display: inline-flex;
    align-items: center;
    min-block-size: 2.75rem;
    color: var(--ec-fg-2);
    text-decoration: underline 1px;
    text-underline-offset: 3px;
}

.ts-footer__pay li {
    display: inline-flex;
    align-items: center;
    min-block-size: 2.75rem;
    font-weight: 700;
}

.ts-footer__main > .ts-module:has(.ts-tools) {
    grid-column: 1 / -1;
    grid-row: 21;
    padding-block-start: 0.75rem;
}

@media (hover: hover) and (pointer: fine) {
    .ts-footer__col:not(.ts-footer__brand) a:hover,
    .ts-footer__legal a:hover {
        color: var(--ec-fg);
        text-decoration: underline 1.5px;
        text-underline-offset: 3px;
    }
}

@media (min-width: 48rem) {
    .ts-footer {
        --fm-mark: 2rem;
        padding-block: 4rem 2rem;
        font-size: 1.0625rem;
        line-height: 1.5;
    }

    .ts-footer > .ts-container {
        grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr));
        column-gap: 3rem;
    }

    .ts-footer__brand {
        grid-column: 1;
        gap: 1rem;
        margin: 0;
    }

    .ts-footer__col:not(.ts-footer__brand) {
        grid-row: span 2;
        margin: 0;
    }

    .ts-footer__col :is(h2, h5),
    .ts-footer__col .ts-module__title {
        margin-block-end: 0.75rem;
        font-size: 1.0625rem;
        line-height: 1.5rem;
    }

    /* Each link is a 44px row (§953), the rows touching, so the rhythm stays close to the board. */
    .ts-footer__col:not(.ts-footer__brand) ul {
        display: flex;
        flex-direction: column;
        gap: 0;
        margin-block-start: -0.625rem;
    }

    .ts-footer__col:not(.ts-footer__brand) a {
        display: inline-flex;
        align-items: center;
        min-block-size: 2.75rem;
        line-height: 1.5rem;
    }

    .ts-footer__main > .ts-module:has(.ts-pulse) {
        grid-column: 1;
        margin: 0;
        padding-block-start: 1.5rem;
    }

    .ts-footer .ts-pulse__value {
        font-size: var(--fm-t-numeral-xs);
        line-height: 2rem;
    }

    .ts-footer__bottom {
        gap: 0 1.5rem;
        min-block-size: 4.3125rem;
        margin-block-start: 2.5rem;
        padding-block-start: 1.5rem;
        font-size: 1rem;
    }

    /* The tools share the bar's row, not its cells (the later bar painted over them and took
       their clicks): the bar spans two columns and the gap, the tools the last two. */
    .ts-footer:has(.ts-tools) .ts-footer__bottom {
        grid-column: 1 / 3;
        margin-inline-end: -3rem;
        padding-inline-end: 3rem;
    }

    .ts-footer__main > .ts-module:has(.ts-tools) {
        display: flex;
        justify-content: flex-end;
        grid-column: 3 / -1;
        grid-row: 20;
        min-inline-size: 0;
        margin-block-start: 2.5rem;
        padding-block-start: 1.5rem;
        border-block-start: 1px solid var(--ec-border);
    }
}

/* ---- Scheme toggle and languages (community "tools" block): footer and drawer ---- */

.ts-tools {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
}

.ts-tools__scheme {
    display: inline-flex;
    align-items: center;
    gap: 0.125rem;
    min-block-size: 3.125rem;
    padding: 0.125rem;
    border: 1px solid var(--fm-control);
    border-radius: var(--ec-btn-radius);
}

.ts-tools__scheme-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    min-block-size: 2.75rem;
    padding: 0 0.75rem;
    border: 0;
    border-radius: var(--fm-r-toggle-inner);
    background: transparent;
    color: var(--ec-fg-2);
    font: inherit;
    font-size: 1rem;
    font-weight: 500;
    line-height: 1;
    cursor: pointer;
    transition: color var(--ec-dur-1) var(--ec-ease), background-color var(--ec-dur-1) var(--ec-ease);
}

.ts-tools__scheme-button svg {
    inline-size: 1rem;
    block-size: 1rem;
    stroke-width: 1.75;
}

.ts-tools__scheme-button[aria-pressed="true"] {
    background-color: var(--fm-toggle-on);
    box-shadow: inset 0 0 0 1px var(--fm-control);
    color: var(--ec-fg);
    font-weight: 700;
}

.ts-tools__scheme-button:focus-visible {
    outline-offset: -2px;
}

@media (hover: hover) and (pointer: fine) {
    .ts-tools__scheme-button:hover {
        color: var(--ec-fg);
    }
}

.ts-tools__language-list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ts-tools__language {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    min-block-size: 3.125rem;
    padding: 0 0.875rem;
    border: 1px solid var(--fm-control);
    border-radius: var(--ec-btn-radius);
    color: var(--ec-fg-2);
    font-weight: 500;
    text-decoration: none;
}

.ts-tools__language svg {
    inline-size: 1.125rem;
    block-size: 1.125rem;
    stroke-width: 1.75;
}

.ts-tools__language--active {
    color: var(--ec-fg);
    font-weight: 700;
}

@media (min-width: 48rem) {
    .ts-tools__scheme {
        gap: 0.25rem;
        min-block-size: 2.75rem;
        padding: 0.1875rem;
    }

    .ts-tools__scheme {
        min-block-size: 3.125rem;
    }

    .ts-tools__language {
        min-block-size: 2.75rem;
    }
}

/* ==========================================================================
   9. Megamenu skin (library megamenu.css owns the mechanics; single-class selectors so the
      skin wins by source order): a surface bubble with the overlay shadow, plain labels.
   ========================================================================== */

.ts-mega {
    border-color: var(--ec-border);
    background: var(--ec-surface);
    box-shadow: var(--fm-overlay-shadow);
}

.ts-mega__title {
    color: var(--ec-fg-2);
    font-family: var(--ec-font-body);
    font-size: 0.9375rem;
    font-weight: 700;
    letter-spacing: normal;
    text-transform: none;
}

.ts-mega__links a {
    color: var(--ec-fg);
    text-decoration: none;
}

.ts-mega__badge {
    border-radius: var(--fm-r-tag);
    background: var(--fm-lit);
    color: var(--fm-lit-fg);
}

.ts-mega-toggle {
    border-radius: 0.375rem;
}

/* ==========================================================================
   Forced colours (Windows High Contrast): the brand mark, button shapes, the facade's legend
   and its busiest and lit panes keep their meaning in system colours.
   ========================================================================== */

@media (forced-colors: active) {
    /* Backplates are painted per line box: the big numerals get a line box as tall as their
       glyphs, so they no longer paint over the weekday or pane label above them. */
    :root :is(.fm-datechip, .fm-pane) :is(.fm-datechip__day, .fm-pane__value) {
        line-height: 1.2;
    }

    /* ...and the facade rows grow with them instead of clipping a pane's last line. */
    :root .fm-facade .fm-facade__grid {
        grid-template-rows: none;
        grid-auto-rows: minmax(10rem, auto);
    }

    /* State carried by fills comes back as system-colour edges: event days, today, the current
       map track; the bands drop their author-colour border-image frame. */
    .fm-week__day--lit {
        border-block-start: 3px solid Highlight;
    }

    .fm-week__day--today {
        outline: 1px solid CanvasText;
        outline-offset: -1px;
    }

    :root .fm-map__track {
        border-block-end-color: Canvas;
    }

    :root .fm-map__track--current {
        border-block-end-color: Highlight;
    }

    .ts-row[data-ts-row="below-top"],
    .ts-row[data-ts-row="band"],
    .ts-row[data-ts-row="cta"],
    .ts-row:has(> .ts-pos-bottom-a),
    .ts-row:has(> .ts-pos-footer-top) {
        border-image: none;
    }

    .ts-brand__text::before,
    .ts-header__nav::before,
    .fm-error__mark {
        forced-color-adjust: none;
        background: CanvasText;
    }

    :is(.ts-button, .ts-btn, .fm-btn--ink):not(.ts-btn--outline) {
        border: 2px solid ButtonText;
    }

    /* The pressed scheme keeps a Highlight frame (its fill is lost here). */
    .ts-tools__scheme-button[aria-pressed="true"] {
        outline: 2px solid Highlight;
        outline-offset: -2px;
    }

    .fm-legend__item::before {
        forced-color-adjust: none;
        box-shadow: none;
        background: Canvas;
        outline: 1px solid CanvasText;
    }

    .fm-legend__item--busiest::before {
        background: Highlight;
    }

    .fm-legend__item--lit::before {
        background: linear-gradient(CanvasText, CanvasText) top / 100% 3px no-repeat, Canvas;
    }

    .fm-pane--busiest {
        border: 3px solid Highlight;
    }

    .fm-pane--lit {
        border-block-start: 3px solid CanvasText;
    }

    :is(.fm-band, .ts-row, .ts-main) :is(.fm-band__stool, .fm-art) {
        color: CanvasText;
    }
}

/* FORME chrome: restrained wordmark, generous header and quiet footer. */
.ts-header { border-block-end: 1px solid var(--ec-border); }
.ts-header__inner { min-block-size: 5.25rem; }
.ts-header .ts-brand__text, .ts-footer .ts-brand__text { font-size: 1.4rem; font-weight: 700; letter-spacing: .12em; }
.ts-brand__text::before, .ts-header__nav::before, .fm-error__mark {
    background: var(--ec-fg);
    -webkit-mask: url('../images/favicon.svg') center / contain no-repeat;
    mask: url('../images/favicon.svg') center / contain no-repeat;
    inline-size: 1.35rem; block-size: 1.35rem;
}
.ts-brand__text { gap: .75rem; }
.ts-header .ts-brand__logo { block-size: 2rem; }
.ts-header__nav .mod-menu > li.current > a::after,
.ts-header__nav .mod-menu > li.active > a::after { block-size: 1px; background: var(--ec-fg); }
.ts-footer { padding-block: var(--ec-sect-y) 2rem; border-block-start: 1px solid var(--ec-border); }
.ts-footer__blurb { max-inline-size: 24rem; line-height: 1.65; }
.ts-footer__col:not(.ts-footer__brand) :is(h2,h5,.ts-module__title) { font-family: var(--ec-font-body); font-weight: 600; font-size: .875rem; letter-spacing: .07em; text-transform: uppercase; }
.ts-footer__bottom { font-size: .875rem; }
.ts-row[data-ts-row="breadcrumbs"] { padding-block: 1.5rem 0; }
.ts-row[data-ts-row="breadcrumbs"] + .ts-row[data-ts-row="content"] { padding-block-start: 2rem; }
.ts-home .ts-row[data-ts-row="breadcrumbs"] { display: none; }
.ts-row[data-ts-row="content"]:has(.fm-landing) { padding-block: 0; }
/* Only an opening hero/section supplies its own top padding. Simple page
   headings retain the component row's normal opening space. */
.ts-row[data-ts-row="content"]:has(.fm-page > :is(.fm-hero, .fm-section):first-child) { padding-block-start: 0; }
@media (min-width: 56.25rem) {
    /* Keep the six-link menu on one line within the boxed header, including
       wide screens where the site search becomes an inline field. The same
       900px breakpoint is used by the framework's accessible drawer runtime. */
    .ts-header__inner { min-block-size: 6rem; gap: clamp(.5rem, 1vw, 1.5rem); }
    .ts-header .ts-brand { flex: none; }
    .ts-header__nav .mod-menu { flex-wrap: nowrap; gap: clamp(.5rem, calc(2vw - .75rem), 1.25rem); }
    .ts-header__nav .mod-menu > li > a { font-weight: 500; }
}
@media (max-width: 47.999rem) { .ts-footer > .ts-container { grid-template-columns: repeat(2,minmax(0,1fr)); gap: 1rem; } }
