/* ===========================================================================
   BestAccessoriesIndia.in - public stylesheet
   Mobile-first. No framework. One file, hand-authored.

   Layout contract:
     - a side gutter of at least 16px at every width
     - every grid/flex child gets min-width:0 so nothing can push the page wide
     - tables, code and ad rails scroll inside their own container
     - the article column never drops below a comfortable reading measure;
       the ad rails are the flexible element, not the content
   =========================================================================== */

/* --- Design tokens ------------------------------------------------------- */
/* Design tokens live in tokens.css, which every layout links before
   this file. Both stylesheets used to declare their own copy of the
   palette; they had already drifted, and a brand change meant editing
   the same value twice and hoping. */


/* --- Reset --------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: .01ms !important;
        transition-duration: .01ms !important;
    }
}

body {
    margin: 0;
    background: var(--canvas);
    color: var(--ink-700);
    font-family: var(--sans);
    font-size: 16px;
    line-height: 1.6;
    /* Backstop against any child that tries to push the page sideways. */
    overflow-x: clip;
}

img, svg, video { max-width: 100%; height: auto; }
img { display: block; }

h1, h2, h3, h4 {
    margin: 0;
    color: var(--ink-900);
    line-height: 1.22;
    letter-spacing: -.012em;
    text-wrap: balance;
    font-weight: 600;
}

p, ul, ol { margin: 0; }
ul, ol { padding-left: 1.15rem; }

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--accent-strong); }

button, input, select, textarea { font: inherit; color: inherit; }

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

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

.skip-link {
    position: absolute; left: -9999px; top: 0; z-index: 200;
    background: var(--ink-900); color: #fff; padding: 12px 18px;
    border-radius: 0 0 var(--r-ctrl) 0; font-weight: 600;
}
.skip-link:focus { left: 0; color: #fff; }

.wrap {
    width: 100%;
    max-width: var(--wrap);
    margin-inline: auto;
    padding-inline: var(--gutter);
}
.wrap--narrow { max-width: 820px; }

.muted { color: var(--ink-500); }
.dot { color: var(--ink-300); margin-inline: .35em; }
.nowrap { white-space: nowrap; }

/* --- Typography scale ---------------------------------------------------- */
.hero__title    { font-size: clamp(28px, 6.2vw, 44px); letter-spacing: -.022em; font-weight: 700; }
.page-head__title, .article__title { font-size: clamp(26px, 5.4vw, 40px); letter-spacing: -.02em; font-weight: 700; }
.section__title { font-size: clamp(20px, 3.4vw, 27px); font-weight: 700; }
.card__title    { font-size: 17px; font-weight: 600; letter-spacing: -.008em; }

.eyebrow {
    font-size: 11.5px; letter-spacing: .11em; text-transform: uppercase;
    font-weight: 600; color: var(--accent); margin: 0 0 10px;
}
.eyebrow--link { display: inline-flex; align-items: center; min-height: 24px; text-decoration: none; }
.eyebrow--link:hover { text-decoration: underline; }

/* --- Buttons ------------------------------------------------------------- */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    min-height: 44px; padding: 10px 18px;
    border: 1px solid transparent; border-radius: var(--r-ctrl);
    font-size: 15px; font-weight: 600; line-height: 1.2;
    text-decoration: none; cursor: pointer;
    transition: background-color .16s ease, border-color .16s ease, color .16s ease;
}
.btn--primary { background: var(--accent); color: #fff; }
.btn--primary:hover { background: var(--accent-strong); color: #fff; }
.btn--ghost { background: var(--surface); border-color: var(--line); color: var(--ink-700); }
.btn--ghost:hover { border-color: var(--ink-300); color: var(--ink-900); }
.btn--commerce { background: var(--commerce); color: #fff; }
.btn--sm { min-height: 36px; padding: 6px 12px; font-size: 13.5px; }
.btn--block { width: 100%; }

.chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 4px 9px; border: 1px solid var(--line); border-radius: var(--r-chip);
    background: var(--surface); color: var(--ink-500);
    font-size: 12.5px; font-weight: 600; text-decoration: none;
}
.chip:hover { border-color: var(--accent); color: var(--accent); }

/* --- Header -------------------------------------------------------------- */
.site-header {
    position: sticky; top: env(safe-area-inset-top, 0px); z-index: 60;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
}
.site-header.is-stuck { box-shadow: var(--sh-sm); }

.site-header__inner {
    display: flex; align-items: center; gap: 16px;
    min-height: 60px;
}

/* --- The logo ------------------------------------------------------------
   The artwork carries its own colour and spacing, so the only job here is to
   give it a height and let the width follow. The width and height attributes
   are in the markup, so the header reserves its space before the file lands
   and nothing jumps.
   ----------------------------------------------------------------------- */
.brand-logo { display: block; flex: none; }
.brand-logo img { display: block; width: auto; }

.brand { display: flex; align-items: center; text-decoration: none; color: inherit; }
.brand__logo img { height: 42px; }
@media (max-width: 519px) { .brand__logo img { height: 34px; } }
@media (max-width: 359px) { .brand__logo img { height: 30px; } }
/* The logo is the link's entire content, so the focus ring has to show
   around the artwork rather than around a text box that is not there. */
.brand:focus-visible { outline-offset: 4px; }

.nav-toggle {
    margin-left: auto; display: grid; place-items: center;
    width: 44px; height: 44px;
    background: none; border: 1px solid var(--line); border-radius: var(--r-ctrl);
    cursor: pointer;
}
.nav-toggle__bars { display: grid; gap: 4px; }
.nav-toggle__bars span { display: block; width: 18px; height: 2px; background: var(--ink-700); border-radius: 1px; }

.site-nav { display: none; }
.site-nav.is-open {
    display: block;
    position: absolute; left: 0; right: 0; top: 100%;
    background: var(--surface); border-bottom: 1px solid var(--line);
    box-shadow: var(--sh-md);
    padding: 8px var(--gutter) 20px;
    max-height: calc(100vh - 60px); overflow-y: auto;
}
.site-nav__list { list-style: none; margin: 0; padding: 0; }
.site-nav__item { position: relative; border-bottom: 1px solid var(--line-soft); }
.site-nav__link {
    display: block; padding: 13px 0; min-height: 44px;
    color: var(--ink-700); text-decoration: none; font-size: 15.5px; font-weight: 600;
}
/* The current page is marked twice: the accent colour, and a rule in the
   logo's own orange under the label. Colour alone would leave the state
   invisible to anyone who cannot separate the two hues, and the rule is
   what makes the header feel like it belongs to the mark above it. */
.site-nav__link.is-active { color: var(--accent); }
@media (min-width: 900px) {
    .site-nav__link { position: relative; }
    .site-nav__link.is-active::after {
        content: ""; position: absolute; left: 0; right: 0; bottom: 6px;
        height: 2px; border-radius: 2px; background: var(--accent-vivid);
    }
}
.site-nav__expand {
    position: absolute; right: 0; top: 4px;
    width: 40px; height: 40px; background: none; border: 0; cursor: pointer;
}
.caret {
    display: inline-block; width: 7px; height: 7px; margin-left: 6px;
    border-right: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor;
    transform: rotate(45deg) translateY(-2px);
}
.nav-panel { display: none; padding: 0 0 12px; }
.nav-panel.is-open { display: block; }
.nav-panel__list { list-style: none; margin: 0; padding: 0; }
.nav-panel__list a {
    display: flex; justify-content: space-between; gap: 12px;
    padding: 9px 0 9px 12px; font-size: 14.5px;
    color: var(--ink-500); text-decoration: none;
    border-left: 2px solid var(--line);
}
.nav-panel__list a:hover { color: var(--accent); border-left-color: var(--accent); }
.nav-panel__count { color: var(--ink-300); font-variant-numeric: tabular-nums; font-size: 12.5px; }
.nav-panel__all {
    display: inline-flex; align-items: center; min-height: 24px;
    margin-top: 8px; margin-left: 12px;
    font-size: 13.5px; font-weight: 600;
}

.site-search { display: flex; gap: 8px; margin-top: 16px; }
.site-search__input {
    flex: 1; min-width: 0; min-height: 44px;
    padding: 9px 12px; border: 1px solid var(--line); border-radius: var(--r-ctrl);
    background: var(--canvas); font-size: 15px;
}
.site-search__input:focus { background: var(--surface); }
.site-search__button {
    display: grid; place-items: center; width: 44px; min-height: 44px;
    border: 1px solid var(--line); border-radius: var(--r-ctrl);
    background: var(--surface); color: var(--ink-500); cursor: pointer;
}
.site-search__button:hover { color: var(--accent); border-color: var(--accent); }

@media (min-width: 900px) {
    .nav-toggle { display: none; }
    .site-header__inner { min-height: 64px; gap: 28px; }
    .site-nav {
        display: flex; align-items: center; gap: 20px;
        margin-left: auto; position: static; padding: 0; box-shadow: none;
        border: 0; max-height: none; overflow: visible;
    }
    .site-nav__list { display: flex; align-items: center; gap: 4px; }
    .site-nav__item { border: 0; }
    .site-nav__link { padding: 8px 12px; border-radius: var(--r-ctrl); font-size: 15px; }
    .site-nav__link:hover { background: var(--canvas); }
    .site-nav__expand { display: none; }

    .site-nav__item.has-panel .nav-panel {
        display: block;
        position: absolute; top: calc(100% + 6px); left: 0;
        min-width: 280px; padding: 12px;
        background: var(--surface); border: 1px solid var(--line);
        border-radius: var(--r-card); box-shadow: var(--sh-md);
        opacity: 0; visibility: hidden; transform: translateY(-4px);
        transition: opacity .14s ease, transform .14s ease, visibility .14s;
    }
    .site-nav__item.has-panel:hover .nav-panel,
    .site-nav__item.has-panel:focus-within .nav-panel,
    .site-nav__item.has-panel .nav-panel.is-open {
        opacity: 1; visibility: visible; transform: none;
    }
    .nav-panel__list a { padding: 8px 10px; border-left: 0; border-radius: var(--r-ctrl); }
    .nav-panel__list a:hover { background: var(--accent-soft); }
    .nav-panel__all { margin-left: 10px; }

    .site-search { margin: 0; width: 240px; }
}

/* --- Flash messages ------------------------------------------------------ */
.flash-stack { max-width: var(--wrap); margin: 16px auto 0; padding-inline: var(--gutter); display: grid; gap: 8px; }
.flash {
    display: flex; align-items: flex-start; gap: 12px;
    padding: 12px 14px; border-radius: var(--r-ctrl);
    border: 1px solid var(--line); background: var(--surface); font-size: 14.5px;
}
.flash--success { border-color: rgba(14,122,86,.35); background: rgba(14,122,86,.07); color: var(--success); }
.flash--error   { border-color: rgba(179,50,47,.35); background: rgba(179,50,47,.07); color: var(--danger); }
.flash--warning { border-color: rgba(140,98,6,.35); background: rgba(140,98,6,.08); color: var(--warning); }
.flash__close { margin-left: auto; background: none; border: 0; font-size: 20px; line-height: 1; cursor: pointer; color: inherit; }

/* --- Hero ---------------------------------------------------------------- */
.hero { background: var(--surface); border-bottom: 1px solid var(--line); }
.hero__inner { display: grid; gap: 32px; padding-block: 44px 48px; }
.hero__content { min-width: 0; }
.hero__lede {
    font-family: var(--serif); font-size: 18px; line-height: 1.65;
    color: var(--ink-500); margin-top: 14px; max-width: 54ch;
}
.hero__search { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 26px; max-width: 560px; }
.hero__search-input {
    flex: 1 1 240px; min-width: 0; min-height: 48px;
    padding: 12px 16px; font-size: 16px;
    border: 1px solid var(--line); border-radius: var(--r-ctrl); background: var(--canvas);
}
.hero__search-input:focus { background: var(--surface); }
.hero__stats {
    display: flex; flex-wrap: wrap; gap: 8px 20px;
    margin-top: 20px; font-size: 14px; color: var(--ink-500);
    font-variant-numeric: tabular-nums;
}
.hero__stats strong { color: var(--ink-900); }

.hero__panel {
    min-width: 0; padding: 22px;
    background: var(--canvas); border: 1px solid var(--line); border-radius: var(--r-panel);
}
.hero__panel-title { font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-300); }
.hero__panel-list { list-style: none; padding: 0; margin: 14px 0 0; display: grid; gap: 12px; font-size: 14.5px; }
.hero__panel-list strong { color: var(--ink-900); }

@media (min-width: 960px) {
    .hero__inner { grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: 56px; align-items: start; padding-block: 64px 68px; }
}

/* --- Sections ------------------------------------------------------------ */
.main { display: block; }
.section { padding-block: 44px; }
.section--tint { background: var(--surface); border-block: 1px solid var(--line); }
.section--trust { background: var(--surface); border-top: 1px solid var(--line); padding-block: 44px 52px; }

.section__head {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 12px;
    margin-bottom: 22px;
}
/* Standalone links - a section's "see all", a pager step, a category eyebrow,
   a byline name, a footer nav item - are controls, not words in a sentence, so
   WCAG 2.2's 24x24 minimum (2.5.8) applies to them. Measured before this, they
   were 18-22px tall: .section__more 79x22, .pagination__step 46x22,
   .eyebrow--link 105x18, the byline link 99x22 and every footer link 20px.
   Each gets its height from the line box rather than from padding, so none of
   them moves anything around it. */
.section__more {
    margin-left: auto; display: inline-flex; align-items: center; min-height: 24px;
    font-size: 14px; font-weight: 600; text-decoration: none;
}
.section__more:hover { text-decoration: underline; }

.page-head { padding-block: 34px 26px; }
.page-head__lede {
    font-family: var(--serif); font-size: 17.5px; line-height: 1.6;
    color: var(--ink-500); margin-top: 12px; max-width: 62ch;
}
.page-head__meta { margin-top: 12px; font-size: 13.5px; color: var(--ink-300); font-variant-numeric: tabular-nums; }

/* --- Cards --------------------------------------------------------------- */
.card-grid { display: grid; gap: 16px; }
.card-grid > * { min-width: 0; }
@media (min-width: 620px) { .card-grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 980px) { .card-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; } }

.card {
    display: flex; flex-direction: column; min-width: 0;
    background: var(--surface);
    border: 1px solid var(--line); border-radius: var(--r-card);
    box-shadow: var(--sh-sm);
    overflow: hidden;
    transition: border-color .16s ease, transform .16s ease;
}
.card:hover { border-color: var(--ink-300); }

.card--tool { padding: 18px; gap: 10px; }
.card__link { display: flex; align-items: flex-start; gap: 12px; text-decoration: none; color: inherit; }
.card__icon {
    display: grid; place-items: center; flex: none;
    width: 36px; height: 36px; border-radius: 8px;
    background: var(--accent-soft); color: var(--accent);
}
.card__title { margin: 0; }
.card--tool .card__title { padding-top: 6px; }
.card__link:hover .card__title { color: var(--accent); }
.card__text { font-size: 14.5px; color: var(--ink-500); line-height: 1.55; }
.card__meta { margin-top: auto; padding-top: 4px; font-size: 13px; color: var(--ink-300); }

.card--article .card__body { padding: 16px 18px 18px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
/* An article card's title is the card's only link, so it is the card's target.
   As an inline box it was 20px tall on a 226px line; as an inline-flex box it
   takes the 24px the criterion asks for without changing where the title sits
   or how it wraps. The tool card next to it already linked the whole card. */
.card--article .card__title a {
    display: inline-flex; align-items: center; min-height: 24px;
    color: inherit; text-decoration: none;
}
.card--article .card__title a:hover { color: var(--accent); }
.card__media { display: block; background: var(--canvas); aspect-ratio: 16 / 9; max-width: 100%; }
.card__media img { width: 100%; height: 100%; object-fit: cover; }
.card__eyebrow { font-size: 11.5px; letter-spacing: .09em; text-transform: uppercase; font-weight: 600; color: var(--accent); }
.card--compact { box-shadow: none; }

/* --- Category tiles ------------------------------------------------------ */
.category-grid {
    list-style: none; padding: 0; margin: 0;
    display: grid; gap: 12px;
    /* A wider floor so the rows divide sensibly. auto-fill at 200px put the six
       categories into five columns and left the sixth alone on a row of its
       own - the one shape to avoid, because a single tile on its own row reads
       as a mistake. At 260px the same six land four and two, and the ladder
       below that is 3 at 1024, 2 at 768 and 1 on a phone. The count is
       editable, so this is a floor that degrades well rather than a column
       count tuned to today's six. */
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
.category-tile {
    display: flex; flex-direction: column; gap: 4px;
    padding: 16px 18px; min-height: 76px;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card);
    text-decoration: none; color: inherit;
    transition: border-color .16s ease, background-color .16s ease;
}
.category-tile:hover { border-color: var(--accent); background: var(--accent-soft); }
.category-tile__name { font-weight: 600; color: var(--ink-900); font-size: 15px; }
.category-tile__count { font-size: 12.5px; color: var(--ink-300); font-variant-numeric: tabular-nums; }

/* --- Filter bar ---------------------------------------------------------- */
.filter-bar {
    display: flex; gap: 8px; margin-bottom: 24px;
    overflow-x: auto; padding-bottom: 6px;
    -webkit-overflow-scrolling: touch; scrollbar-width: thin;
}
.filter-bar__item {
    flex: none; display: inline-flex; align-items: center; gap: 7px;
    padding: 8px 14px; min-height: 40px;
    border: 1px solid var(--line); border-radius: 100px;
    background: var(--surface); color: var(--ink-500);
    font-size: 14px; font-weight: 600; text-decoration: none; white-space: nowrap;
}
.filter-bar__item:hover { border-color: var(--ink-300); color: var(--ink-900); }
.filter-bar__item.is-active { background: var(--ink-900); border-color: var(--ink-900); color: #fff; }
.filter-bar__count { font-size: 12px; opacity: .7; font-variant-numeric: tabular-nums; }

/* --- Marketplace rail ---------------------------------------------------- */
.marketplace-rail {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
    margin-bottom: 20px; padding-bottom: 18px;
    border-bottom: 1px solid var(--line);
}
.marketplace-rail__label {
    font-size: 11.5px; letter-spacing: .09em; text-transform: uppercase;
    color: var(--ink-300); font-weight: 600; margin-right: 4px;
}
.chip--marketplace {
    display: inline-flex; align-items: center; gap: 7px;
    min-height: 34px; padding: 6px 12px; font-weight: 600;
    text-decoration: none;
}
.chip__count {
    font-size: 11.5px; font-weight: 500; color: var(--ink-300);
    font-variant-numeric: tabular-nums;
}

/* --- Tool hub ------------------------------------------------------------ */
.featured-tools { margin-bottom: 34px; }

.tool-browse {
    display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px;
    margin-bottom: 22px;
}
.tool-browse .filter-bar { margin: 0; flex: 1 1 auto; }

.tool-filter { display: flex; gap: 8px; flex: 0 1 320px; min-width: 0; }
.tool-filter__input { flex: 1 1 auto; min-width: 0; min-height: 42px; font-size: 15px; }
.tool-filter .btn { flex: 0 0 auto; min-height: 42px; }
.tool-filter__empty {
    margin-top: 20px; padding: 22px; text-align: center;
    background: var(--surface); border: 1px dashed var(--line); border-radius: var(--r-card);
    color: var(--ink-500); font-size: 14.5px;
}
.tool-filter__empty[hidden] { display: none; }
.tool-list__item[hidden] { display: none; }

/* --- Trust grid ---------------------------------------------------------- */
.trust-grid {
    list-style: none; padding: 0; margin: 24px 0 0;
    display: grid; gap: 22px;
}
.trust-grid h3 { font-size: 16px; margin-bottom: 6px; }
.trust-grid p { font-size: 14.5px; color: var(--ink-500); }
.trust-grid__more { margin-top: 22px; font-size: 14px; color: var(--ink-500); }
@media (min-width: 760px) { .trust-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 28px; } }

/* --- Article layout ------------------------------------------------------
   The rails only appear when the viewport can afford them without squeezing
   the reading column. Below 1200px there are no rails at all.

   The track list follows the rails the page actually has, which is why every
   state is named rather than assumed. The template renders each rail only when
   its advertisement slot is live, so the number of children varies from one to
   three; a single positional three-track list handed two children puts the
   article in the left rail's 160px track and the advertisement in the reading
   column. That is not a hypothetical - measured at 1440px with a right rail and
   no left rail, the article came out 160px wide, 18 characters a line.
   -------------------------------------------------------------------------- */
.article-layout { display: grid; gap: 32px; padding-block: 8px 40px; }
.article-layout > * { min-width: 0; }
.article-layout__rail { display: none; }
/* A rail whose advertisement resolved to nothing. app.js sets this once the
   slots have answered, and the layout modifier changes with it, so the grid
   stops holding a track for a rail that has nothing to put in it. */
.article-layout__rail.is-vacant,
.tool-layout__rail.is-vacant { display: none !important; }

/* One column until 1200px, whatever the state: both rails are display:none
   below that, so a track for either would be a track with nothing in it. */
.article-layout--bare { grid-template-columns: minmax(0, 1fr); }

@media (min-width: 1200px) {
    .article-layout--both,
    .article-layout--right { grid-template-columns: minmax(0, 1fr) 300px; gap: 40px; }
    .article-layout__rail--right { display: block; }
}
@media (min-width: 1400px) {
    .article-layout--both { grid-template-columns: 160px minmax(0, 1fr) 300px; gap: 48px; }
    .article-layout--left { grid-template-columns: 160px minmax(0, 1fr); gap: 48px; }
    .article-layout--right { gap: 48px; }
    .article-layout__rail--left { display: block; }
}

.rail-sticky { position: sticky; top: 90px; }

.article { max-width: 760px; }
.article--page { max-width: none; }

/* With no right rail there is no 300px track beside the article, so there is
   nothing for it to sit hard left against: it centres in the space it has.

   The measure itself is deliberately left alone. Measured with the page's own
   serif, .prose at 760px is already about 84 characters a line, which is at the
   wide end of comfortable - widening the running text to fill 1216px would make
   the article harder to read, not better, and the brief for this change asks for
   a comfortable measure to be kept. So the layout reclaims the space and the
   paragraphs keep the width they were designed at. */
.article-layout--bare > .article,
.article-layout--left > .article { margin-inline: auto; }
.article__head { padding-block: 20px 0; }
.article__standfirst {
    font-family: var(--serif); font-size: 19px; line-height: 1.6;
    color: var(--ink-500); margin-top: 14px;
}
.article__byline {
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px;
    margin-top: 20px; padding-bottom: 20px;
    border-bottom: 1px solid var(--line);
    font-size: 13.5px; color: var(--ink-500);
}
.article__byline-name { display: flex; flex-direction: column; }
.article__byline-name a { display: inline-flex; align-items: center; min-height: 24px; font-weight: 600; text-decoration: none; color: var(--ink-900); }
.article__byline-role { color: var(--ink-300); font-size: 12.5px; }
.article__byline-meta { color: var(--ink-300); }

.avatar {
    display: grid; place-items: center; flex: none;
    width: 40px; height: 40px; border-radius: 50%;
    background: var(--accent-soft); color: var(--accent-strong);
    font-size: 13px; font-weight: 700; letter-spacing: .02em;
}
.avatar--sm { width: 30px; height: 30px; font-size: 11px; }
.avatar--lg { width: 64px; height: 64px; font-size: 20px; }

.article__figure { margin: 24px 0 0; }
.article__figure img { width: 100%; border-radius: var(--r-card); background: var(--canvas); }
.article__figure figcaption { margin-top: 8px; font-size: 13px; color: var(--ink-300); }

.article__tags { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 32px; }
.article__tags-label { font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-300); font-weight: 600; }

.article__corrections { margin-top: 28px; font-size: 13.5px; color: var(--ink-300); }

.author-box {
    display: flex; gap: 16px; margin-top: 34px; padding: 20px;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card);
}
.author-box__body { min-width: 0; }
.author-box__name { font-weight: 600; color: var(--ink-900); }
.author-box__name span { display: block; font-weight: 400; font-size: 13px; color: var(--ink-300); }
.author-box__bio { margin-top: 8px; font-size: 14.5px; color: var(--ink-500); }

/* --- Prose (article and page body) --------------------------------------- */
.prose { font-family: var(--serif); font-size: 17.5px; line-height: 1.72; color: var(--ink-700); }
@media (min-width: 900px) { .prose { font-size: 18px; } }

.prose > * + * { margin-top: 1.1em; }
.prose h2 { font-family: var(--sans); font-size: 1.42em; margin-top: 1.9em; scroll-margin-top: 90px; }
.prose h3 { font-family: var(--sans); font-size: 1.16em; margin-top: 1.6em; scroll-margin-top: 90px; }
.prose ul, .prose ol { padding-left: 1.3em; }
.prose li + li { margin-top: .4em; }
.prose a { text-decoration: underline; }
.prose img { border-radius: var(--r-card); margin-block: 1.4em; }
.prose blockquote {
    margin-inline: 0; padding: 4px 0 4px 20px;
    border-left: 3px solid var(--commerce); color: var(--ink-500);
}
.prose code {
    font-family: var(--mono); font-size: .85em;
    background: var(--canvas); border: 1px solid var(--line);
    border-radius: 3px; padding: 1px 5px;
}
.prose pre {
    font-family: var(--mono); font-size: 13px; line-height: 1.55;
    background: var(--canvas); border: 1px solid var(--line);
    border-radius: var(--r-card); padding: 16px; overflow-x: auto;
}
.prose pre code { background: none; border: 0; padding: 0; }
.prose hr { border: 0; border-top: 1px solid var(--line); margin-block: 2em; }

/* Tables scroll inside their own container - the page never does. */
.prose table {
    width: 100%; border-collapse: collapse;
    font-family: var(--sans); font-size: 14.5px;
    font-variant-numeric: tabular-nums;
    display: block; overflow-x: auto; -webkit-overflow-scrolling: touch;
}
@media (min-width: 760px) { .prose table { display: table; } }
.prose th, .prose td { padding: 10px 14px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
.prose th { background: var(--canvas); font-weight: 600; color: var(--ink-900); white-space: nowrap; }

/* --- Authored classes --------------------------------------------------
   The five class names the article editor writes, and the only ones it
   writes. They exist because the sanitiser strips style= from a saved body:
   an editor that centred a paragraph with style="text-align:center" would
   lose the centring on save, so the editor writes a class and the meaning
   lives here instead. admin.css carries the same five under .ed__surface so
   the editor shows what the page will do.

   Nothing generates these. An author who wants a different callout colour
   changes the modifier in HTML mode; anything else they invent is simply an
   unstyled class, which is why the sanitiser can allow class= at all.
   ---------------------------------------------------------------------- */
.prose .text-left { text-align: left; }
.prose .text-center { text-align: center; }
.prose .text-right { text-align: right; }
.prose .text-justify { text-align: justify; }
.prose .callout {
    margin: 22px 0; padding: 14px 18px;
    border-left: 4px solid var(--accent);
    border-radius: 0 var(--r-ctrl) var(--r-ctrl) 0;
    background: var(--canvas);
    font-family: var(--sans); font-size: 15px; color: var(--ink-700);
}
.prose .callout > :first-child { margin-top: 0; }
.prose .callout > :last-child { margin-bottom: 0; }
.prose .callout--warn { border-left-color: var(--danger); }
.prose .callout--tip { border-left-color: var(--success); }

.affiliate-disclosure {
    margin: 20px 0; padding: 12px 16px;
    background: var(--commerce-soft); border: 1px solid rgba(179, 92, 34, .25);
    border-radius: var(--r-ctrl);
    font-family: var(--sans); font-size: 13.5px; color: var(--ink-700);
}

/* --- Tool page -----------------------------------------------------------
   The calculator is the reason the page exists, so it gets the panel, the
   shadow and the top of the screen. Everything below it is reading matter
   and is styled like the rest of the site.

   Two columns on a wide screen (figures left, result right), stacked on a
   phone with the result directly under the button that produces it.
   -------------------------------------------------------------------------- */
.tool-layout { display: grid; gap: 32px; padding-bottom: 40px; }
.tool-layout > * { min-width: 0; }
.tool-layout__rail { display: none; }
@media (min-width: 1200px) {
    .tool-layout { grid-template-columns: minmax(0, 1fr) 300px; gap: 40px; }
    .tool-layout__rail { display: block; }
}
.tool-layout--bare { grid-template-columns: minmax(0, 1fr) !important; }

.page-head--tool { padding-bottom: 20px; }
.page-head--tool .page-head__lede { max-width: 60ch; }

.tool-panel {
    background: var(--surface);
    border: 1px solid var(--line); border-radius: var(--r-panel);
    box-shadow: var(--sh-md);
    padding: 20px;
    scroll-margin-top: 84px;
}
@media (min-width: 700px) { .tool-panel { padding: 26px 28px; } }

.tool-panel__grid { display: grid; gap: 24px; align-items: start; }
@media (min-width: 880px) {
    .tool-panel__grid { grid-template-columns: minmax(0, 1.12fr) minmax(290px, .88fr); gap: 32px; }
}
.tool-panel__inputs { min-width: 0; }

.tool-panel__heading {
    font-size: 11.5px; letter-spacing: .11em; text-transform: uppercase;
    color: var(--ink-300); font-weight: 600; margin-bottom: 14px;
}
.tool-panel__placeholder, .tool-panel__notice { color: var(--ink-500); font-size: 14.5px; }
.tool-panel__notice h2 { margin-bottom: 8px; }
.tool-panel__notice-links { margin-top: 14px; }

/* --- Tool form controls --------------------------------------------------
   Site-side form styling. The admin has its own, denser set; these are
   sized for thumbs and for typing a number once, not for editing records.
   -------------------------------------------------------------------------- */
.tool-form__group {
    font-size: 11.5px; letter-spacing: .11em; text-transform: uppercase;
    color: var(--ink-300); font-weight: 600;
    margin: 22px 0 12px; padding-top: 16px; border-top: 1px solid var(--line-soft);
}
.tool-form__group:first-child { margin-top: 0; padding-top: 0; border-top: 0; }

.field { margin-bottom: 16px; min-width: 0; }
.field:last-of-type { margin-bottom: 0; }
.field__label {
    display: block; margin-bottom: 6px;
    font-size: 14px; font-weight: 600; color: var(--ink-900);
}
.field__optional {
    margin-left: 6px; font-weight: 400; font-size: 12px;
    color: var(--ink-300); text-transform: none; letter-spacing: 0;
}
.field__hint { margin-top: 6px; font-size: 12.5px; color: var(--ink-500); line-height: 1.5; }
.field__unit { font-size: 13px; color: var(--ink-300); white-space: nowrap; }
.field__error {
    margin-top: 6px; font-size: 12.5px; font-weight: 500; color: var(--danger); line-height: 1.5;
}
.field__error[hidden] { display: none; }

.tool-field__set { border: 0; padding: 0; margin: 0; min-width: 0; }
.tool-field__set legend { padding: 0; }
.tool-field[hidden] { display: none; }

.input {
    width: 100%; min-height: 46px;
    padding: 10px 13px;
    font: inherit; font-size: 16px; color: var(--ink-900);
    background: var(--surface);
    border: 1px solid var(--line); border-radius: var(--r-ctrl);
    transition: border-color .14s ease, box-shadow .14s ease;
}
.input::placeholder { color: var(--ink-300); }
.input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); outline: none; }
.input:disabled { background: var(--canvas); color: var(--ink-300); }
.input--compact { min-height: 40px; width: 7.5ch; padding: 8px 6px; text-align: right; font-size: 15px; }

/* Numbers read better right-aligned and in tabular figures - a column of
   amounts lines up on the decimal point the way a receipt does. */
input[type="number"].input, input[type="number"] { font-variant-numeric: tabular-nums; }
input[type="number"].input::-webkit-outer-spin-button,
input[type="number"].input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type="number"].input { -moz-appearance: textfield; }

select.input {
    appearance: none; padding-right: 34px; cursor: pointer;
    background-image:
        linear-gradient(45deg, transparent 50%, var(--ink-300) 50%),
        linear-gradient(135deg, var(--ink-300) 50%, transparent 50%);
    background-position: calc(100% - 17px) calc(50% + 1px), calc(100% - 12px) calc(50% + 1px);
    background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}

/* A prefix (Rs) and a suffix (%, km) sit flush against the box rather than
   floating inside it, so the affix never overlaps a long number. The corner
   radii follow position, which keeps one rule set working for an input with
   a prefix, a suffix, both, or neither. */
.input-wrap { display: flex; align-items: stretch; }
.input-wrap > * { border-radius: 0; }
.input-wrap > :first-child {
    border-start-start-radius: var(--r-ctrl); border-end-start-radius: var(--r-ctrl);
}
.input-wrap > :last-child {
    border-start-end-radius: var(--r-ctrl); border-end-end-radius: var(--r-ctrl);
}
.input-wrap__prefix, .input-wrap__suffix {
    display: grid; place-items: center; padding-inline: 12px;
    background: var(--canvas); border: 1px solid var(--line);
    color: var(--ink-500); font-size: 14.5px; font-weight: 600; white-space: nowrap;
}
.input-wrap__prefix { border-right: 0; }
.input-wrap__suffix { border-left: 0; }
.input-wrap .input:focus { position: relative; z-index: 1; }

.range-row { display: flex; align-items: center; gap: 14px; }
.range-row__value { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.range {
    flex: 1 1 auto; min-width: 0; height: 30px; padding: 0;
    appearance: none; background: transparent; cursor: pointer;
}
.range::-webkit-slider-runnable-track { height: 4px; border-radius: 2px; background: var(--line); }
.range::-moz-range-track { height: 4px; border-radius: 2px; background: var(--line); }
.range::-webkit-slider-thumb {
    appearance: none; width: 20px; height: 20px; margin-top: -8px;
    border-radius: 50%; background: var(--accent); border: 2px solid #fff;
    box-shadow: var(--sh-sm);
}
.range::-moz-range-thumb {
    width: 20px; height: 20px; border-radius: 50%;
    background: var(--accent); border: 2px solid #fff; box-shadow: var(--sh-sm);
}
.range:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px var(--accent-soft); }
.range:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 4px var(--accent-soft); }

.choice-row { display: flex; flex-wrap: wrap; gap: 8px; }
.choice {
    display: inline-flex; align-items: center; gap: 8px;
    min-height: 44px; padding: 8px 14px 8px 12px;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-ctrl);
    font-size: 14.5px; color: var(--ink-700); cursor: pointer;
    transition: border-color .14s ease, background-color .14s ease;
}
.choice:hover { border-color: var(--ink-300); }
.choice input { width: 17px; height: 17px; margin: 0; accent-color: var(--accent); flex: 0 0 auto; }
.choice:has(input:checked) {
    border-color: var(--accent); background: var(--accent-soft); color: var(--ink-900); font-weight: 600;
}
.choice:has(input:focus-visible) { box-shadow: 0 0 0 3px var(--accent-soft); }
.choice--single { width: 100%; }

.has-error .input,
.has-error .input-wrap__prefix,
.has-error .input-wrap__suffix { border-color: var(--danger); }
.has-error .input:focus { box-shadow: 0 0 0 3px rgba(179, 50, 47, .12); }
.has-error .field__label { color: var(--danger); }

/* --- Examples and actions ------------------------------------------------ */
.tool-examples {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
    margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--line-soft);
}
.tool-examples__label {
    width: 100%; font-size: 11.5px; letter-spacing: .09em; text-transform: uppercase;
    color: var(--ink-300); font-weight: 600;
}
.chip--button { cursor: pointer; font: inherit; font-size: 13px; min-height: 34px; }
.chip--button:hover { background: var(--accent-soft); }

.tool-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 20px; }
.tool-actions .btn--primary { flex: 1 1 auto; min-width: 150px; }
.tool-actions__hint { margin-top: 10px; font-size: 12.5px; color: var(--ink-300); }

/* --- Result card ---------------------------------------------------------
   Tinted rather than bordered-and-white so the answer is visibly the
   destination of the form, not another field in it.
   -------------------------------------------------------------------------- */
.tool-panel__result { min-width: 0; }
.tool-result {
    padding: 20px; border-radius: var(--r-card);
    background: var(--accent-soft); border: 1px solid var(--accent-line);
}
/* The result column was sticky, which worked while it held only a headline
   figure. With a fee breakdown under it the column is long, and a pinned card
   covers the rows scrolling beneath it - so the result stays in flow. */

/* The label sits behind a short bar in the logo's orange, which is what
   tells the eye where the answer is without turning the whole card orange. */
.tool-result__label {
    font-size: var(--t-label); letter-spacing: .1em; text-transform: uppercase;
    color: var(--ink-500); font-weight: 700;
    display: flex; align-items: center; gap: 8px;
}
.tool-result__label::before {
    content: ""; flex: none; width: 18px; height: 3px; border-radius: 2px;
    background: var(--accent-vivid);
}
.tool-result__value {
    margin-top: 8px;
    font-family: var(--mono); font-size: clamp(26px, 5.6vw, 34px); font-weight: 500;
    color: var(--ink-900); font-variant-numeric: tabular-nums;
    letter-spacing: -.02em; line-height: 1.15;
    overflow-wrap: anywhere;
}
.tool-result__value--empty { color: var(--ink-300); }
.tool-result__caption { margin-top: 8px; font-size: 13.5px; color: var(--ink-500); line-height: 1.55; }
.tool-result__message { margin-top: 8px; font-size: 14.5px; color: var(--ink-700); line-height: 1.55; }

.tool-result__list {
    margin: 18px 0 0; padding-top: 14px;
    border-top: 1px solid var(--accent-line);
    display: grid; gap: 10px;
}
.tool-result__row {
    display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
}
.tool-result__row dt { font-size: 14px; color: var(--ink-500); min-width: 0; }
.tool-result__row dd {
    margin: 0; font-family: var(--mono); font-size: 15px; font-weight: 500;
    color: var(--ink-900); font-variant-numeric: tabular-nums;
    text-align: right; white-space: nowrap;
}
.tool-result__note { display: block; font-size: 12px; color: var(--ink-300); margin-top: 2px; }
.tool-result__footnote {
    margin-top: 14px; padding-top: 12px;
    border-top: 1px solid var(--accent-line);
    font-size: 12.5px; color: var(--ink-500); line-height: 1.5;
}
.tool-result__actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.tool-result__actions .btn[hidden] { display: none; }

.tool-disclaimer {
    margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--line);
    font-size: 13px; color: var(--ink-500); line-height: 1.6;
}
.tool-disclaimer strong { color: var(--ink-700); }
/* The article caps its running text at 760px - about 84 characters in the
   page's serif - and says why a few hundred lines up. The tool page's prose
   sections had no cap at all, so at 1440 they ran to 876px and about 97
   characters: the same typeface, the same role, a measurably harder line to
   read, and wider than the deliberate maximum set for the article. They now
   share the article's measure. The panels, tables and related lists keep the
   full column; this applies only to the running text. */
.tool-section { margin-top: 38px; }
.tool-section.prose { max-width: 760px; }
.tool-section > h2:first-child { margin-top: 0; }

/* --- Fee breakdown -------------------------------------------------------
   A statement, not a chart. A seller reads a payout down a column, so the
   breakdown is a column: what you start with, what comes off, what is left.
   No bars, no colour coding beyond the sign - the figures carry it.
   -------------------------------------------------------------------------- */
.waterfall {
    margin-top: 20px; padding-top: 18px;
    border-top: 1px solid var(--line);
}
.waterfall[hidden] { display: none; }
.waterfall__title {
    font-size: 11.5px; letter-spacing: .11em; text-transform: uppercase;
    color: var(--ink-300); font-weight: 600; margin-bottom: 12px;
}
.waterfall__list { margin: 0; display: grid; gap: 0; }

.waterfall__row {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 16px; padding: 7px 0;
    border-bottom: 1px solid var(--line-soft);
}
.waterfall__row:last-child { border-bottom: 0; }
.waterfall__row dt { font-size: 14px; color: var(--ink-700); min-width: 0; }
.waterfall__row dd {
    margin: 0; font-family: var(--mono); font-size: 14.5px;
    color: var(--ink-700); font-variant-numeric: tabular-nums;
    text-align: right; white-space: nowrap;
}
.waterfall__note {
    display: block; margin-top: 2px;
    font-size: 12px; color: var(--ink-300); line-height: 1.45;
}

.waterfall__row--start dt,
.waterfall__row--start dd { font-weight: 600; color: var(--ink-900); }

.waterfall__row--deduction dd { color: var(--danger); }

/* A subtotal and the total are the two places the eye should stop, so they
   get a rule above them rather than a colour. */
.waterfall__row--subtotal {
    border-top: 1px solid var(--line); margin-top: 4px; padding-top: 10px;
}
.waterfall__row--subtotal dt,
.waterfall__row--subtotal dd { font-weight: 600; color: var(--ink-900); }

.waterfall__row--total {
    border-top: 2px solid var(--ink-900); border-bottom: 0;
    margin-top: 6px; padding-top: 12px;
}
.waterfall__row--total dt {
    font-size: 15px; font-weight: 700; color: var(--ink-900);
}
.waterfall__row--total dd {
    font-size: 19px; font-weight: 600; color: var(--ink-900); letter-spacing: -.01em;
}

/* --- Calculation assumptions --------------------------------------------- */
.tool-assumptions {
    margin-top: 20px; padding: 14px 16px;
    background: var(--canvas); border: 1px solid var(--line-soft);
    border-radius: var(--r-ctrl);
}
.tool-assumptions[hidden] { display: none; }
.tool-assumptions__title {
    font-size: 11.5px; letter-spacing: .1em; text-transform: uppercase;
    color: var(--ink-300); font-weight: 600; margin-bottom: 8px;
}
.tool-assumptions ul {
    margin: 0; padding-left: 1.1em;
    display: grid; gap: 5px;
    font-size: 13px; color: var(--ink-500); line-height: 1.55;
}

/* --- Unconfigured-rate notice -------------------------------------------- */
.rate-notice {
    margin-top: 18px; padding: 14px 16px;
    background: var(--commerce-soft); border: 1px solid rgba(179, 92, 34, .25);
    border-radius: var(--r-ctrl);
    font-size: 13.5px; color: var(--ink-700); line-height: 1.6;
}
.rate-notice strong { display: block; color: var(--ink-900); margin-bottom: 4px; }
.rate-notice__meta {
    margin-top: 8px; font-size: 12.5px; color: var(--ink-500);
}

/* --- Variable table (the formula's symbols) ------------------------------ */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.variable-table {
    width: 100%; margin-top: 18px; border-collapse: collapse;
    font-family: var(--sans); font-size: 14.5px;
}
.variable-table th, .variable-table td {
    padding: 10px 14px; border-bottom: 1px solid var(--line);
    text-align: left; vertical-align: top;
}
.variable-table thead th {
    background: var(--canvas); color: var(--ink-500);
    font-size: 11.5px; letter-spacing: .09em; text-transform: uppercase; font-weight: 600;
    white-space: nowrap;
}
.variable-table tbody th {
    font-family: var(--mono); font-weight: 500; color: var(--ink-900); white-space: nowrap;
}
.variable-table tbody td:last-child { color: var(--ink-500); white-space: nowrap; }

/* --- Article table of contents -------------------------------------------
   A tinted block rather than a bordered one, so it reads as an aside to the
   article instead of as its first section. Only rendered when there are at
   least three headings to point at.
   -------------------------------------------------------------------------- */
.toc {
    margin: 28px 0 32px; padding: 18px 20px;
    background: var(--canvas); border-radius: var(--r-card);
}
.toc__title {
    font-size: 11.5px; letter-spacing: .1em; text-transform: uppercase;
    color: var(--ink-300); font-weight: 600; margin-bottom: 10px;
}
.toc__list { margin: 0; padding: 0; list-style: none; display: grid; gap: 7px; }
.toc__item { font-size: 15.5px; line-height: 1.45; }
/* h3 entries indented under the h2 they belong to. */
.toc__item--h3 { padding-left: 18px; font-size: 14.5px; }
.toc__item a { color: var(--ink-700); text-decoration-color: var(--line); }
.toc__item a:hover { color: var(--accent); }

/* The anchors the contents list points at. Without this a jump puts the
   heading under the sticky header instead of below it. */
.prose h2[id], .prose h3[id] { scroll-margin-top: 84px; }

.article-faq { margin-top: 44px; }

/* --- FAQ ----------------------------------------------------------------- */
.faq { margin-top: 18px; border-top: 1px solid var(--line); }
.faq__item { border-bottom: 1px solid var(--line); }
.faq__question {
    list-style: none; cursor: pointer;
    padding: 16px 32px 16px 0; position: relative;
    font-weight: 600; color: var(--ink-900); font-size: 16px;
}
.faq__question::-webkit-details-marker { display: none; }
.faq__question::after {
    content: ""; position: absolute; right: 6px; top: 22px;
    width: 8px; height: 8px;
    border-right: 1.8px solid var(--ink-300); border-bottom: 1.8px solid var(--ink-300);
    transform: rotate(45deg); transition: transform .16s ease;
}
.faq__item[open] .faq__question::after { transform: rotate(-135deg); }
.faq__answer { padding-bottom: 18px; font-size: 16.5px; }

/* --- Related / lists ----------------------------------------------------- */
.related { margin-top: 44px; }
.related__title { font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-300); margin-bottom: 16px; }

.link-list { list-style: none; padding: 0; margin: 0; border-top: 1px solid var(--line); }
.link-list li { padding: 14px 0; border-bottom: 1px solid var(--line-soft); }
.link-list a { display: inline-flex; align-items: center; min-height: 24px; font-weight: 600; text-decoration: none; }
.link-list a:hover { text-decoration: underline; }
.link-list__meta { display: block; margin-top: 3px; font-size: 13.5px; color: var(--ink-300); }

/* --- Author page --------------------------------------------------------- */
.author-head { display: flex; gap: 18px; align-items: center; padding-block: 34px 22px; }
.author-head__name { font-size: clamp(24px, 4.6vw, 32px); }
.author-head__role { color: var(--accent); font-weight: 600; font-size: 14.5px; margin-top: 2px; }
.author-head__credentials { color: var(--ink-500); font-size: 14px; margin-top: 4px; }
.author-head__contact { font-size: 14px; margin-top: 6px; }

/* --- Search -------------------------------------------------------------- */
.search-form { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.search-form__input {
    flex: 1 1 240px; min-width: 0; min-height: 48px;
    padding: 12px 16px; font-size: 16px;
    border: 1px solid var(--line); border-radius: var(--r-ctrl); background: var(--surface);
}

/* --- Empty state --------------------------------------------------------- */
.empty-state {
    padding: 44px 24px; text-align: center;
    background: var(--surface); border: 1px dashed var(--line); border-radius: var(--r-card);
}
.empty-state__title { font-size: 18px; }
.empty-state__body { margin: 8px auto 18px; max-width: 46ch; color: var(--ink-500); font-size: 14.5px; }

/* --- Pagination ---------------------------------------------------------- */
.pagination {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
    gap: 8px 14px; margin-block: 36px 8px;
}
.pagination__list { list-style: none; display: flex; gap: 4px; padding: 0; margin: 0; }
.pagination__list a, .pagination__list .is-current, .pagination__gap {
    display: grid; place-items: center; min-width: 40px; min-height: 40px;
    padding: 0 10px; border-radius: var(--r-ctrl);
    font-size: 14.5px; font-weight: 600; text-decoration: none;
    font-variant-numeric: tabular-nums;
}
.pagination__list a { color: var(--ink-500); border: 1px solid var(--line); background: var(--surface); }
.pagination__list a:hover { border-color: var(--accent); color: var(--accent); }
.pagination__list .is-current { background: var(--ink-900); color: #fff; }
.pagination__gap { color: var(--ink-300); }
.pagination__step {
    display: inline-grid; place-items: center; min-height: 40px; padding-inline: 10px;
    font-size: 14px; font-weight: 600; text-decoration: none;
}
.pagination__step.is-disabled { color: var(--ink-300); }

/* --- Breadcrumbs --------------------------------------------------------- */
.breadcrumbs { max-width: var(--wrap); margin-inline: auto; padding: 16px var(--gutter) 0; }
.breadcrumbs__list {
    list-style: none; display: flex; flex-wrap: wrap; gap: 6px;
    padding: 0; margin: 0; font-size: 13px; color: var(--ink-300);
}
.breadcrumbs__item a { display: inline-flex; align-items: center; min-height: 24px; color: var(--ink-500); text-decoration: none; }
.breadcrumbs__item a:hover { color: var(--accent); text-decoration: underline; }
.breadcrumbs__sep { margin-left: 6px; }

/* --- Ad slots ------------------------------------------------------------
   A slot reserves its height before the ad arrives, so filling it shifts
   nothing. Device targeting is CSS-only so one cached page serves every
   device.

   What it must not do is keep that space when nothing arrives. Measured on
   this build with the ad script blocked - which is what an ad-blocker user,
   a no-fill response and the whole pre-approval period all look like - the
   reserved-but-empty boxes came to 2,255px on a desktop article, 1,324px on
   the same article at 390px, and 1,093px on a desktop calculator. The first
   line of a phone article began at y=1,693 on an 844px screen: two screens
   of labelled empty rectangles before a word of the article.

   So the slot has three states, and only one of them is visible:

     probing  the height is reserved and nothing is drawn - no border, no
              fill, no label - because we do not yet know whether there is
              an advertisement to label.
     filled   a creative arrived: the container takes its frame and its
              label, which is what the label is for.
     empty    nothing arrived: the slot collapses and the page closes up.

   Ad Manager already calls collapseEmptyDivs(), and AdSense marks an
   unfilled <ins> with data-ad-status="unfilled"; both collapse the unit
   while this wrapper kept its padding, border, label and reserved height
   around the hole. The states below are what close that gap.
   -------------------------------------------------------------------------- */
.ad-slot {
    display: block; margin-block: 28px;
    padding: 8px; border: 1px solid transparent; border-radius: var(--r-ctrl);
    text-align: center;
}
.ad-slot[data-ad-state="filled"] {
    border-color: var(--line-soft); background: var(--canvas);
}
/* The label describes an advertisement. Until one is there it has nothing to
   describe, so it is not shown and - because visibility:hidden also takes it
   out of the accessibility tree - not announced either.

   visibility rather than display: the label keeps its line in the layout while
   the slot is probing, so revealing it when the creative lands costs nothing.
   Measured as display:none, that reveal moved everything below the slot down
   by 30px at every width - a layout shift introduced by the very code meant to
   prevent one. An empty slot is removed outright, so the reserved line costs
   nothing there either. */
.ad-slot__label {
    display: block; visibility: hidden; margin-bottom: 6px;
    font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-300);
}
.ad-slot[data-ad-state="filled"] .ad-slot__label { visibility: visible; }
/* A grid rather than a block: an <iframe> or an <ins> is an inline box, so in a
   block container it sits on a text baseline and the line box adds a few pixels
   under it. Measured, that was an 8px downward shift of the whole page at the
   moment a correctly sized creative landed. A grid has no baseline to sit on,
   and it centres the creative in a unit wider than itself. */
.ad-slot__unit { display: grid; place-items: center; line-height: 0; min-height: var(--ad-h-mobile, 280px); }
@media (min-width: 600px)  { .ad-slot__unit { min-height: var(--ad-h-tablet, 280px); } }
@media (min-width: 1000px) { .ad-slot__unit { min-height: var(--ad-h-desktop, 250px); } }
/* A filled unit keeps its reserved floor. Releasing it looked tidier - a short
   creative no longer sat in a taller box - but a slot that shrinks the moment
   the ad lands moves everything under it up, which is the layout shift the
   reservation exists to prevent. The reservation is only released for a slot
   that resolved to empty, and that one is removed outright. */

/* No script, no observer: the slot still has to resolve. The stylesheet
   reserves nothing when JavaScript is off, because nothing will ever fill it.
   app.js removes this class as its first act, before any paint it controls. */
.no-js .ad-slot { display: none; }

.ad-slot[data-ad-devices="desktop"],
.ad-slot[data-ad-devices="desktop tablet"] { display: none; }
@media (min-width: 600px) {
    .ad-slot[data-ad-devices="desktop tablet"] { display: block; }
    .ad-slot[data-ad-devices="mobile"] { display: none; }
}
@media (min-width: 1000px) {
    .ad-slot[data-ad-devices="desktop"] { display: block; }
    .ad-slot[data-ad-devices="tablet"],
    .ad-slot[data-ad-devices="mobile tablet"] { display: none; }
}

/* Collapsed completely: no height, no margin, no border - the page reads as if
   the slot were never there.

   This has to come after the device-targeting rules above. They set display at
   the same specificity, so a desktop rail that resolved to empty went on being
   shown at 618px by the later rule - which is how an empty rail survived the
   collapse the first time this was written. */
.ad-slot[data-ad-state="empty"] { display: none; }

/* --- Footer -------------------------------------------------------------- */
.site-footer {
    background: var(--ink-900); color: var(--ink-on-dark-body);
    padding-block: 44px 28px; margin-top: 56px;
    padding-bottom: calc(28px + env(safe-area-inset-bottom, 0px));
}
.site-footer__grid { display: grid; gap: 30px; }
@media (min-width: 700px) { .site-footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .site-footer__grid { grid-template-columns: 1.4fr repeat(3, minmax(0, 1fr)); gap: 40px; } }

.site-footer__logo img { height: 54px; }
.site-footer__tagline { font-size: 14px; margin-top: 4px; max-width: 34ch; }
.site-footer__contact { margin-top: 12px; font-size: 14px; }
.site-footer a { color: var(--ink-on-dark-link); text-decoration: none; }
.site-footer a:hover { color: var(--ink-on-dark); text-decoration: underline; }
.site-footer__heading { font-size: 11.5px; letter-spacing: .11em; text-transform: uppercase; color: var(--ink-on-dark-muted); margin-bottom: 12px; }
.site-footer__list { list-style: none; padding: 0; margin: 0; display: grid; gap: 4px; font-size: 14px; }
.site-footer__list a { display: inline-flex; align-items: center; min-height: 24px; }

.site-footer__disclosure {
    margin-top: 36px; padding-top: 22px; border-top: 1px solid rgba(255,255,255,.1);
    font-size: 13px; color: #8E9AAA; display: grid; gap: 10px; max-width: 90ch;
}
.site-footer__disclosure strong { color: var(--ink-on-dark-strong); }
.site-footer__disclosure .affiliate-disclosure {
    background: rgba(255,255,255,.04); border-color: rgba(255,255,255,.12); color: #A8B4C4;
}
.site-footer__base {
    margin-top: 22px; padding-top: 18px; border-top: 1px solid rgba(255,255,255,.1);
    display: flex; flex-wrap: wrap; gap: 6px 20px; font-size: 12.5px; color: var(--ink-on-dark-muted);
}
.site-footer__meta { margin-left: auto; }

/* The way back to the notification card. A link in everything but element: it
   has to be a button because it opens something on this page rather than going
   anywhere, and a link that goes nowhere is worse for a screen reader than a
   button that looks like one. */
.site-footer__push {
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 2px;
    cursor: pointer;
}

.site-footer__push:hover { color: var(--ink-on-dark); }
.site-footer__push[hidden] { display: none; }

/* --- Error page ---------------------------------------------------------- */
.error-page { padding-block: 12vh 15vh; max-width: 620px; text-align: center; }
.error-page__code {
    font-family: var(--mono); font-size: 56px; font-weight: 500;
    color: var(--accent); font-variant-numeric: tabular-nums; line-height: 1;
}
.error-page__title { font-size: clamp(24px, 5vw, 32px); margin-top: 14px; }
.error-page__message { margin-top: 12px; color: var(--ink-500); font-size: 16.5px; }
.error-page__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin-top: 28px; }
.error-page__detail {
    margin-top: 32px; padding: 16px; text-align: left;
    font-family: var(--mono); font-size: 12px; line-height: 1.5;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-ctrl);
    overflow-x: auto; white-space: pre-wrap; word-break: break-word;
}

/* A preview is an admin-only view of a page that is not live. The bar says so
   on the page itself, because the rest of the page is deliberately identical
   to the real one. */
.preview-bar {
    background: var(--brand-dark); color: #fff;
    font-size: 13.5px; line-height: 1.5;
}
.preview-bar__inner {
    display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: baseline;
    padding-top: 10px; padding-bottom: 10px;
}
.preview-bar strong {
    flex: none; text-transform: uppercase; letter-spacing: .06em; font-size: 11.5px;
    padding: 2px 8px; border-radius: 999px; background: var(--accent-vivid);
}
.preview-bar span { flex: 1 1 320px; min-width: 0; opacity: .85; }
.preview-bar__edit { flex: none; color: #fff; text-decoration: underline; }

/* --- Notification opt-in ---------------------------------------------------
   A floating card rather than a strip in the footer. The footer version was
   only ever seen by somebody who had already scrolled to the bottom, which is
   not where a visitor decides they want to hear from a site again.

   Deliberately not an interstitial: it does not cover the content, it does not
   darken the page behind it, and it has a close button that works. Google
   penalises intrusive interstitials on mobile and it would deserve to here.

   Desktop: a card at the bottom centre. Phones: a bottom sheet across the
   width, above the home indicator.
   ------------------------------------------------------------------------- */
.push-card {
    position: fixed;
    z-index: 60;
    left: 50%;
    bottom: max(16px, env(safe-area-inset-bottom, 0px));
    transform: translateX(-50%);
    width: min(34rem, calc(100vw - 32px));
    padding: 16px;
    background: var(--surface);
    color: var(--ink-700);
    border: 1px solid var(--line);
    border-radius: var(--r-panel);
    /* The dialog step, not the panel one: this sits above the page. */
    box-shadow: var(--sh-dialog);
    /* Restated: .push-card sets display, which beats the browser's own
       [hidden] rule, so the attribute alone would not hide it. */
    animation: push-card-in .22s ease-out both;
}

.push-card[hidden] { display: none; }

@keyframes push-card-in {
    from { opacity: 0; transform: translateX(-50%) translateY(10px); }
    to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* Somebody who asked for less motion gets the card, not the movement. */
@media (prefers-reduced-motion: reduce) {
    .push-card { animation: none; }
}

.push-card__inner {
    display: grid;
    grid-template-columns: auto 1fr auto;
    grid-template-areas: "icon text close" ". actions actions";
    gap: 8px 12px;
    align-items: start;
}

.push-card__icon {
    grid-area: icon;
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    border: 1px solid var(--accent-line);
    border-radius: 50%;
    background: var(--accent-soft);
    color: var(--accent);
}

.push-card__icon svg { width: 20px; height: 20px; }

.push-card__text { grid-area: text; min-width: 0; }

.push-card__title {
    margin: 0 0 2px;
    font-size: 16px;
    font-weight: 600;
    line-height: var(--lh-tight);
    color: var(--ink-900);
}

.push-card__body {
    margin: 0;
    font-size: 14px;
    line-height: var(--lh-body);
    color: var(--ink-500);
}

.push-card__actions {
    grid-area: actions;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 4px;
}

/* Each button carries its own [hidden] rule for the same reason the card does:
   .btn sets display: inline-flex, which beats the browser's. */
.push-card__actions .btn[hidden] { display: none; }

.push-card__close {
    grid-area: close;
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    margin: -4px -4px 0 0;
    padding: 0;
    border: 0;
    border-radius: var(--r-ctrl);
    background: none;
    color: var(--ink-300);
    cursor: pointer;
}

.push-card__close:hover { color: var(--ink-900); background: var(--canvas); }
.push-card__close svg { width: 16px; height: 16px; }

/* A live region: it has to hold its space, or every message shifts the card. */
.push-card__status {
    margin: 8px 0 0;
    min-height: 1.4em;
    font-size: 13px;
    color: var(--ink-500);
}

.push-card__status:empty { min-height: 0; margin: 0; }

/* The subscribed state, for as long as the card is still on the screen. */
.push-card.is-done .push-card__icon {
    border-color: var(--success-line);
    background: var(--success-soft);
    color: var(--success);
}

@media (max-width: 34rem) {
    /* A bottom sheet on a phone: full width, square at the bottom, so it reads
       as part of the viewport edge rather than as something floating over it. */
    .push-card {
        left: 0;
        right: 0;
        bottom: 0;
        width: auto;
        transform: none;
        border-radius: var(--r-panel) var(--r-panel) 0 0;
        border-bottom: 0;
        padding-bottom: max(16px, env(safe-area-inset-bottom, 0px));
    }

    @keyframes push-card-in {
        from { opacity: 0; transform: translateY(14px); }
        to   { opacity: 1; transform: translateY(0); }
    }

    /* Full-width buttons, stacked if they do not fit side by side. */
    .push-card__actions .btn { flex: 1 1 auto; }
}
