/* ==========================================================================
   SOBO CULTURE — editorial homepage design system
   Namespaced .so-* / scoped under .so-page so it cannot collide with the
   legacy .tti-* system still used by the interior pages.
   ========================================================================== */

/* .so-body must be in this list: it carries `background: var(--so-canvas)`,
   and without the tokens declared here that resolved to an invalid value,
   leaving the body transparent and falling back to browser white in any area
   .so-page did not cover. */
.so-body,
.so-page,
.so-header,
.so-menu,
.so-footer {
    /* ── Palette ── */
    --so-canvas:  #FCFBF8;
    --so-ink:     #111111;
    --so-muted:   #6E6A63;
    --so-hair:    #E2DED6;
    /* Driven by Appearance > Colors. theme.cache.css defines --theme-accent
       from the saved setting; the literals here are the fallback used before
       a colour has ever been saved, or if that file is missing. */
    --so-accent:  var(--theme-accent, #B5502F);
    --so-accent-tint: var(--theme-accent-tint, #F6EBE5);
    --so-scrim:   linear-gradient(to top, rgba(12,10,9,.78) 0%, rgba(12,10,9,.42) 42%, rgba(12,10,9,0) 100%);

    /* ── Type ── */
    --so-serif: 'Playfair Display', Georgia, 'Times New Roman', serif;
    --so-sans:  'Jost', 'Helvetica Neue', Helvetica, Arial, sans-serif;

    /* ── Metrics ── */
    --so-container: 1240px;
    --so-gutter: 32px;
    --so-gap: 28px;
    --so-rhythm: 96px;
    /* 78px unless a taller logo is saved in Appearance, in which case the bar
       grows to fit rather than clamping the logo. Every other rule derives from
       this var, so the sticky bar, menu row and logo cap all follow. */
    --so-header-h: max(78px, calc(var(--theme-logo-h-desktop, 48px) + 30px));
    --so-ease: cubic-bezier(.2, .6, .2, 1);
}

/* ── Reset / base ─────────────────────────────────────────────────────── */

/* Resets are scoped to .so-body, not .so-page — the header, menu overlay and
   footer live outside <main> and would otherwise keep default link styling. */
.so-body {
    margin: 0;
    background: var(--so-canvas);
    color: var(--so-ink);
    font-family: var(--so-sans);
    -webkit-font-smoothing: antialiased;
    overflow-x: clip;
}
.so-body *,
.so-body *::before,
.so-body *::after { box-sizing: border-box; }

/* :where() keeps the reset at zero specificity, so a single utility class
   still wins. Without it `.so-body p {margin:0}` (0,1,1) silently beats
   `.so-lead-stand {margin-top:26px}` (0,1,0) and every margin below is lost. */
:where(.so-body) a { color: inherit; text-decoration: none; }
:where(.so-body) img { display: block; max-width: 100%; height: auto; }
:where(.so-body) h1, :where(.so-body) h2, :where(.so-body) h3, :where(.so-body) h4,
:where(.so-body) p, :where(.so-body) figure, :where(.so-body) blockquote,
:where(.so-body) ul, :where(.so-body) ol { margin: 0; padding: 0; }
:where(.so-body) ul, :where(.so-body) ol { list-style: none; }

.so-page { background: var(--so-canvas); overflow-x: clip; }

.so-wrap {
    width: 100%;
    max-width: calc(var(--so-container) + var(--so-gutter) * 2);
    margin-inline: auto;
    padding-inline: var(--so-gutter);
}
.so-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: var(--so-gap); }

/* Utility type ------------------------------------------------------- */

.so-util {
    font-family: var(--so-sans);
    font-size: .6875rem;          /* 11px */
    font-weight: 500;
    letter-spacing: .14em;
    text-transform: uppercase;
    line-height: 1;
}
.so-kicker {
    display: inline-block;
    font-family: var(--so-sans);
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--so-accent);
    line-height: 1;
}
.so-byline {
    display: flex;
    align-items: center;
    gap: .75em;
    font-family: var(--so-sans);
    font-size: .6875rem;
    font-weight: 400;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--so-muted);
    line-height: 1;
}
.so-byline .so-bar {
    width: 1px;
    height: 11px;
    background: var(--so-hair);
    display: inline-block;
}

.so-sr {
    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 ---------------------------------------------------------- */
.so-skip {
    position: absolute; left: 12px; top: -60px; z-index: 200;
    background: var(--so-ink); color: var(--so-canvas);
    padding: 12px 18px;
    font-family: var(--so-sans); font-size: .6875rem;
    letter-spacing: .14em; text-transform: uppercase;
    transition: top .2s var(--so-ease);
}
.so-skip:focus { top: 12px; }

/* Focus rings -------------------------------------------------------- */
.so-page a:focus-visible,
.so-page button:focus-visible,
.so-page input:focus-visible,
.so-page [tabindex]:focus-visible,
.so-header a:focus-visible,
.so-header button:focus-visible,
.so-menu a:focus-visible,
.so-menu button:focus-visible,
.so-footer a:focus-visible,
.so-footer button:focus-visible,
.so-footer select:focus-visible {
    outline: 2px solid var(--so-accent);
    outline-offset: 3px;
}

/* ── Media wrapper + hover behaviour ──────────────────────────────────── */

.so-media {
    display: block;
    position: relative;
    overflow: hidden;                 /* image scales inside this */
    background: #EEEAE2;
}
.so-media img {
    width: 100%; height: 100%;
    object-fit: cover;
    transition: transform 500ms var(--so-ease);
}
.so-media--4x5  { aspect-ratio: 4 / 5; }
.so-media--9x16 { aspect-ratio: 9 / 16; }
.so-media--16x9 { aspect-ratio: 16 / 9; }
.so-media--1x1  { aspect-ratio: 1 / 1; }
.so-media--3x4  { aspect-ratio: 3 / 4; }

.so-cardlink:hover .so-media img,
.so-cardlink:focus-visible .so-media img { transform: scale(1.05); }

/* Serif title with wipe-in terracotta underline */
.so-title {
    font-family: var(--so-serif);
    font-weight: 400;
    color: var(--so-ink);
    letter-spacing: -.01em;
}
.so-title span {
    background-image: linear-gradient(var(--so-accent), var(--so-accent));
    background-size: 0% 1px;
    background-position: 0 100%;
    background-repeat: no-repeat;
    transition: background-size 420ms var(--so-ease);
    padding-bottom: .06em;
}
.so-cardlink:hover .so-title span,
.so-cardlink:focus-visible .so-title span { background-size: 100% 1px; }

/* ── Section label + rule ─────────────────────────────────────────────── */

.so-seclabel {
    display: flex;
    align-items: center;
    gap: 20px;
    margin-bottom: 34px;
}
.so-seclabel h2 {
    font-family: var(--so-sans);
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--so-ink);
    white-space: nowrap;
}
.so-seclabel .so-rule {
    flex: 1;
    height: 1px;
    background: var(--so-hair);
    transform-origin: left center;
    transition: transform 900ms var(--so-ease);
}
/* Same progressive-enhancement rule: drawn by default, collapsed only for JS. */
.so-js .so-seclabel .so-rule { transform: scaleX(0); }
.so-js .so-seclabel.is-in .so-rule { transform: scaleX(1); }
.so-seclabel .so-count {
    font-family: var(--so-sans);
    font-size: .6875rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--so-muted);
    white-space: nowrap;
}

/* ══════════════════════════════════════════════════════════════════════
   HEADER
   ══════════════════════════════════════════════════════════════════════ */

.so-header {
    position: sticky;
    top: 0;
    z-index: 90;
    height: var(--so-header-h);
    background: var(--so-canvas);
    border-bottom: 1px solid var(--so-hair);
    transition: transform 420ms var(--so-ease);
}
.so-header.is-hidden { transform: translateY(-100%); }

.so-header-inner {
    height: var(--so-header-h);
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 16px;
}

/* Left: MENU button */
.so-menubtn {
    justify-self: start;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    background: none;
    border: 0;
    padding: 6px 2px;
    cursor: pointer;
    color: var(--so-ink);
    font-family: var(--so-sans);
    font-size: .6875rem;
    font-weight: 500;
    letter-spacing: .14em;
    text-transform: uppercase;
}
.so-menubtn-icon { display: block; width: 20px; }
.so-menubtn-icon span {
    display: block;
    height: 1px;
    background: var(--so-ink);
    transition: transform 300ms var(--so-ease);
}
.so-menubtn-icon span + span { margin-top: 5px; }
.so-menubtn:hover .so-menubtn-icon span:first-child { transform: translateX(3px); }

/* Centre: wordmark */
.so-wordmark {
    justify-self: center;
    text-align: center;
    transition: transform 420ms var(--so-ease);
    transform-origin: center center;
}
.so-header.is-shrunk .so-wordmark { transform: scale(.8); }

/* An uploaded logo needs an explicit height: the base reset sets `height:auto`
   on every image, which overrides the height attribute in the markup, so a tall
   stacked lockup would render at its natural ratio and spill out of the
   fixed-height header onto the ticker below. Height comes from
   Appearance > Logo; max-height keeps it inside the bar whatever is saved. */
.so-wordmark img {
    height: var(--theme-logo-h-desktop, 48px);
    max-height: calc(var(--so-header-h) - 18px);
    width: auto;
    object-fit: contain;
}

/* Light/dark marks. Only one is in the DOM when no dark logo is saved, so the
   light one must stay visible by default rather than relying on the pair. */
.so-wordmark .so-logo--dark { display: none; }
html.dark .so-wordmark .so-logo--light { display: none; }
html.dark .so-wordmark .so-logo--dark  { display: block; }
.so-wordmark-text {
    display: block;
    font-family: var(--so-serif);
    font-weight: 500;
    font-size: clamp(1.5rem, 1.9vw, 1.9rem);
    letter-spacing: .3em;
    text-indent: .3em;               /* offset the trailing letterspace */
    text-transform: uppercase;
    line-height: 1.1;
    white-space: nowrap;
}
.so-wordmark-rule {
    display: block;
    height: 1px;
    background: var(--so-hair);
    margin-top: 5px;
}

/* Right: search + subscribe */
.so-header-right {
    justify-self: end;
    display: inline-flex;
    align-items: center;
    gap: 16px;
}
.so-iconbtn {
    display: inline-grid;
    place-items: center;
    width: 34px; height: 34px;
    background: none; border: 0; padding: 0;
    cursor: pointer; color: var(--so-ink);
}
.so-iconbtn svg { display: block; }

.so-subscribe {
    display: inline-flex;
    align-items: center;
    border: 1px solid var(--so-accent);
    color: var(--so-accent);
    background: transparent;
    padding: 10px 20px;
    font-family: var(--so-sans);
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    line-height: 1;
    cursor: pointer;
    transition: background-color 260ms var(--so-ease), color 260ms var(--so-ease);
}
.so-subscribe:hover { background: var(--so-accent); color: var(--so-canvas); }

/* ── Menu overlay ─────────────────────────────────────────────────────── */

.so-menu {
    position: fixed;
    inset: 0;
    z-index: 120;
    background: var(--so-canvas);
    opacity: 0;
    visibility: hidden;
    transition: opacity 380ms var(--so-ease), visibility 0s linear 380ms;
    overflow-y: auto;
}
.so-menu.is-open {
    opacity: 1;
    visibility: visible;
    transition: opacity 380ms var(--so-ease), visibility 0s;
}
.so-menu-top {
    height: var(--so-header-h);
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: 1px solid var(--so-hair);
}
.so-menu-close {
    display: inline-flex; align-items: center; gap: 10px;
    background: none; border: 0; padding: 6px 2px; cursor: pointer;
    color: var(--so-ink);
    font-family: var(--so-sans); font-size: .6875rem;
    font-weight: 500; letter-spacing: .14em; text-transform: uppercase;
}
.so-menu-body {
    display: grid;
    grid-template-columns: 1.1fr .9fr;
    gap: 60px;
    padding-block: clamp(40px, 6vw, 92px);
    align-items: start;
}
.so-menu-list li + li { margin-top: .1em; }
.so-menu-link {
    display: block;
    font-family: var(--so-serif);
    font-weight: 400;
    font-size: clamp(2.2rem, 5.4vw, 4.2rem);
    line-height: 1.14;
    letter-spacing: -.02em;
    color: var(--so-ink);
    transition: color 260ms var(--so-ease), opacity 260ms var(--so-ease);
}
.so-menu-list:hover .so-menu-link { opacity: .34; }
.so-menu-list .so-menu-link:hover { opacity: 1; color: var(--so-accent); }

.so-menu-preview {
    position: sticky;
    top: 120px;
    aspect-ratio: 4 / 5;
    background: #EEEAE2;
    overflow: hidden;
}
.so-menu-preview img {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity 420ms var(--so-ease);
}
.so-menu-preview img.is-active { opacity: 1; }
.so-menu-preview-cap {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    padding: 20px;
    background: var(--so-scrim);
    color: #fff;
    font-family: var(--so-serif);
    font-size: 1.05rem;
    line-height: 1.3;
    opacity: 0;
    transition: opacity 420ms var(--so-ease);
}
.so-menu-preview-cap.is-active { opacity: 1; }

/* ══════════════════════════════════════════════════════════════════════
   MODULE 1 — Today's Edit
   ══════════════════════════════════════════════════════════════════════ */

.so-today { border-bottom: 1px solid var(--so-hair); }
.so-today-inner {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 28px;
    height: 56px;
}
.so-today-date { color: var(--so-muted); white-space: nowrap; }
.so-today-rot {
    position: relative;
    height: 56px;
    overflow: hidden;
    text-align: center;
}
.so-today-item {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: opacity 700ms var(--so-ease);
    pointer-events: none;
}
.so-today-item.is-active { opacity: 1; pointer-events: auto; }
.so-today-item a {
    font-family: var(--so-serif);
    font-size: 1rem;
    line-height: 1.3;
    color: var(--so-ink);
    text-align: center;
    max-width: 62ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: block;
}
.so-today-item a:hover { color: var(--so-accent); }
.so-today-all { color: var(--so-ink); white-space: nowrap; }
.so-today-all:hover { color: var(--so-accent); }

/* ══════════════════════════════════════════════════════════════════════
   MODULE 2 — Lead story
   ══════════════════════════════════════════════════════════════════════ */

.so-lead { padding-block: 0 calc(var(--so-rhythm) / 2); }
.so-lead-grid {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: var(--so-gap);
    align-items: center;
}
.so-lead-media { grid-column: 1 / span 7; }
.so-lead-well  { grid-column: 8 / span 5; padding-block: clamp(20px, 3vw, 48px); }

/* Image bleeds past the container to the true viewport edge.
   Distance from the container's content edge to the viewport edge is
   (100vw - container) / 2, floored at the gutter on narrow screens. */
.so-lead-media .so-media {
    aspect-ratio: 4 / 5;
    margin-left: calc(-1 * max(var(--so-gutter), (100vw - var(--so-container)) / 2));
}
.so-lead.is-mirrored .so-lead-media { grid-column: 6 / span 7; order: 2; }
.so-lead.is-mirrored .so-lead-well  { grid-column: 1 / span 5; order: 1; }
.so-lead.is-mirrored .so-lead-media .so-media {
    margin-left: 0;
    margin-right: calc(-1 * max(var(--so-gutter), (100vw - var(--so-container)) / 2));
}

.so-lead-title {
    font-family: var(--so-serif);
    font-weight: 400;
    font-size: clamp(2.4rem, 4.4vw, 4.5rem);   /* 56-72px at desktop */
    line-height: 1.04;
    letter-spacing: -.022em;
    margin-top: 18px;
    text-wrap: balance;
}
/* Long titles step down a size so the headline stays ~3 lines instead of 5. */
.so-lead-title.is-long {
    font-size: clamp(1.95rem, 3.1vw, 3.1rem);
    line-height: 1.08;
}
.so-lead-stand {
    font-family: var(--so-serif);
    font-size: 1.25rem;                         /* 20px */
    line-height: 1.55;
    color: var(--so-muted);
    margin-top: 26px;
    max-width: 40ch;
}
.so-lead-meta { margin-top: 26px; }

/* ══════════════════════════════════════════════════════════════════════
   MODULE 3 — The Grid
   ══════════════════════════════════════════════════════════════════════ */

/* Half the rhythm each side, so two adjacent modules total exactly one
   96px gap rather than 192px. */
.so-mod { padding-block: calc(var(--so-rhythm) / 2); }

/* ── Latest carousel ─────────────────────────────────────────────────
   Editorial 4:5 cards with explicit arrow controls and snap. Kept
   deliberately distinct from the Visual Stories rail (9:16, image-only,
   free drag, progress bar) so the two are not the same layout family. */

.so-carousel-outer { position: relative; }

.so-carousel {
    --so-cols: 4;
    display: flex;
    gap: var(--so-gap);
    align-items: stretch;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    /* Start flush with the container, bleed off the right edge. */
    padding-inline: max(var(--so-gutter), (100vw - var(--so-container)) / 2);
    /* Snap ignores padding unless scroll-padding matches it. Without this the
       browser snaps the first card to the raw container edge, leaving the rail
       resting at scrollLeft ~100 and the first card out of line with the label. */
    scroll-padding-inline: max(var(--so-gutter), (100vw - var(--so-container)) / 2);
    padding-bottom: 4px;
    scrollbar-width: none;
    cursor: grab;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
}
.so-carousel::-webkit-scrollbar { display: none; }
.so-carousel.is-dragging { cursor: grabbing; scroll-behavior: auto; scroll-snap-type: none; }
.so-carousel.is-dragging a { pointer-events: none; }

.so-carousel-item {
    flex: 0 0 calc((100% - (var(--so-cols) - 1) * var(--so-gap)) / var(--so-cols));
    scroll-snap-align: start;
    display: flex;
}

/* Cards fill the track height so bylines align across the row. */
.so-card { display: flex; flex: 1; }
.so-card > a { display: flex; flex-direction: column; flex: 1; }
.so-card .so-card-body {
    padding-top: 16px;
    display: flex;
    flex-direction: column;
    flex: 1;
}
.so-card .so-byline { margin-top: auto; padding-top: 12px; }

/* Arrow controls, sitting in the section-label row */
.so-carnav { display: inline-flex; gap: 6px; margin-left: 16px; }
.so-carbtn {
    display: inline-grid;
    place-items: center;
    width: 34px; height: 34px;
    padding: 0;
    background: transparent;
    border: 1px solid var(--so-hair);
    border-radius: 0;
    color: var(--so-ink);
    cursor: pointer;
    transition: border-color .2s var(--so-ease), color .2s var(--so-ease),
                background-color .2s var(--so-ease), opacity .2s var(--so-ease);
}
.so-carbtn:hover:not(:disabled) {
    border-color: var(--so-accent);
    color: var(--so-accent);
}
.so-carbtn:disabled { opacity: .3; cursor: default; }
.so-card .so-kicker { margin-bottom: 10px; }
.so-card-title {
    font-size: 1.3125rem;      /* 21px */
    line-height: 1.25;
}
/* A grid row is as tall as its tallest cell, so one four-line headline
   strands the other three cards in whitespace and pushes the next row out
   of view. Cap at three lines to keep the rows even. */
.so-card-title span {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.so-card .so-byline { margin-top: 12px; }

/* Quote card — every 5th slot */
.so-quote {
    display: flex;
    flex: 1;                       /* fill the carousel cell height */
    flex-direction: column;
    justify-content: center;
    background: var(--so-accent-tint);
    padding: 38px 32px;
    min-height: 100%;
}
.so-quote blockquote {
    font-family: var(--so-serif);
    font-weight: 400;
    font-size: clamp(1.4rem, 1.9vw, 1.75rem);
    line-height: 1.28;
    letter-spacing: -.012em;
    color: var(--so-ink);
    margin: 0;
    text-wrap: pretty;
}
.so-quote blockquote::before { content: "\201C"; }
.so-quote blockquote::after  { content: "\201D"; }
/* Hard 3-line cap: a pull quote is a glance, not a paragraph. */
.so-quote blockquote {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.so-quote figcaption {
    margin-top: 22px;
    font-family: var(--so-sans);
    font-size: .6875rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--so-accent);
}

/* ══════════════════════════════════════════════════════════════════════
   MODULE 4 — One structure per category
   Each family is drawn from the category's own world, not rotated at
   random. No family is used twice on the page.
   ══════════════════════════════════════════════════════════════════════ */

/* ── Arts: pictures hung on a rail, deliberately uneven ──────────────── */
.so-hang {
    position: relative;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--so-gap);
    align-items: start;
}
.so-hang-rail {
    position: absolute;
    left: 0; right: 0; top: 26px;
    height: 1px;
    background: var(--so-hair);
    z-index: 0;
}
.so-hang-item { position: relative; z-index: 1; }
.so-hang-item--0 { margin-top: 0; }
.so-hang-item--1 { margin-top: 54px; }     /* the uneven hang is the point */
.so-hang-item--2 { margin-top: 22px; }
.so-hang-label { padding-top: 14px; }
.so-hang-title { font-size: 1.1875rem; line-height: 1.28; }

/* ── Jewellery: a lit case. Small objects, maximum air, centred. ─────── */
.so-vitrine {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(28px, 4vw, 64px);
    background: var(--so-accent-tint);
    padding: clamp(38px, 5vw, 76px) clamp(28px, 4vw, 64px);
}
.so-vitrine-item { text-align: center; }
.so-vitrine-item .so-media {
    width: clamp(120px, 58%, 190px);
    margin-inline: auto;
}
.so-vitrine-title {
    margin-top: 22px;
    font-size: 1.0625rem;
    line-height: 1.32;
}
.so-vitrine-item .so-kicker { margin-top: 12px; margin-bottom: 0; }

/* ── Women's Wear: a lookbook spread, plates offset, copy between ────── */
.so-lookbook {
    display: grid;
    grid-template-columns: 1fr .82fr 1fr;
    gap: clamp(22px, 3vw, 46px);
    align-items: start;
}
.so-lookbook-plate--b { margin-top: clamp(40px, 7vw, 110px); }
.so-lookbook-copy {
    align-self: center;
    padding-block: 20px;
}
.so-lookbook-entry + .so-lookbook-entry {
    margin-top: 34px;
    padding-top: 34px;
    border-top: 1px solid var(--so-hair);
}
.so-lookbook-title { font-size: 1.25rem; line-height: 1.26; }

/* ── Men's Wear: full-width rows. One rule between, none above or below. */
.so-row2 + .so-row2 { border-top: 1px solid var(--so-hair); }
.so-row2-link {
    display: grid;
    grid-template-columns: 104px 1fr auto;
    gap: clamp(18px, 2.4vw, 38px);
    align-items: center;
    padding-block: clamp(20px, 2.2vw, 30px);
}
.so-row2-thumb { display: block; }
.so-row2-body { display: block; }
.so-row2-title { font-size: 1.25rem; line-height: 1.26; display: block; }
.so-row2-stand {
    display: block;
    margin-top: 8px;
    font-family: var(--so-serif);
    font-size: .9375rem;
    line-height: 1.55;
    color: var(--so-muted);
    max-width: 62ch;
}
.so-row2-meta { color: var(--so-muted); white-space: nowrap; }

/* ── Beauty: shade blocks. Type-led, no photography. ────────────────── */
.so-swatch {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--so-gap);
}
.so-swatch-item {
    /* Held in a custom property so the picture below can cancel it exactly and
       bleed to the panel edge. */
    --so-swatch-pad: clamp(28px, 3vw, 44px);
    padding: var(--so-swatch-pad);
    min-height: clamp(230px, 24vw, 320px);
    display: flex;
}
/* The anchor is the only child, so it has to be the flex column - putting
   space-between on the wrapper distributes nothing and strands the padding. */
.so-swatch-item > a {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    flex: 1;
}
/* Three steps of the same accent: a shade range, which is the subject. */
.so-swatch-item--0 { background: color-mix(in srgb, var(--so-accent) 8%,  var(--so-canvas)); }
.so-swatch-item--1 { background: color-mix(in srgb, var(--so-accent) 15%, var(--so-canvas)); }
.so-swatch-item--2 { background: color-mix(in srgb, var(--so-accent) 24%, var(--so-canvas)); }
.so-swatch-title { font-size: clamp(1.2rem, 1.7vw, 1.5rem); line-height: 1.22; }
.so-swatch-stand {
    margin-top: 14px;
    font-family: var(--so-serif);
    font-size: .9375rem;
    line-height: 1.55;
    color: var(--so-muted);
}
.so-swatch-item .so-byline { margin-top: 24px; }

/* The sample. `margin-top: auto` absorbs the free space before the parent's
   space-between can, so the type stays grouped at the top and the picture is
   pinned to the base; the negative side and bottom margins cancel the panel
   padding so it bleeds to the tint's edge. Cards with no image are untouched. */
.so-swatch-media {
    display: block;
    margin: auto calc(-1 * var(--so-swatch-pad)) calc(-1 * var(--so-swatch-pad));
    padding-top: 26px;
}

/* ── Innovation: text forward. One idea, set large. ─────────────────── */
.so-statement-title {
    font-size: clamp(1.9rem, 4.2vw, 3.4rem);
    line-height: 1.06;
    letter-spacing: -.02em;
    max-width: 26ch;
    text-wrap: balance;
}
.so-statement-stand {
    margin-top: 24px;
    font-family: var(--so-serif);
    font-size: clamp(1.0625rem, 1.3vw, 1.25rem);
    line-height: 1.58;
    color: var(--so-muted);
    max-width: 52ch;
}
.so-statement .so-byline { margin-top: 22px; }
.so-statement-more {
    margin-top: clamp(34px, 4vw, 56px);
    border-top: 1px solid var(--so-hair);
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0 var(--so-gap);
}
.so-statement-more li { padding-top: 22px; }
.so-statement-more-title {
    display: block;
    font-family: var(--so-serif);
    font-size: 1.0625rem;
    line-height: 1.3;
    color: var(--so-ink);
}

/* ── General News: the dateline carries the information ─────────────── */
.so-dateline-item + .so-dateline-item { border-top: 1px solid var(--so-hair); }
.so-dateline-link {
    display: grid;
    grid-template-columns: 76px 1fr;
    gap: clamp(20px, 2.6vw, 40px);
    align-items: baseline;
    padding-block: clamp(20px, 2.2vw, 30px);
}
.so-dateline-date { display: block; text-align: center; }
.so-dateline-day {
    display: block;
    font-family: var(--so-serif);
    font-size: clamp(1.9rem, 2.6vw, 2.5rem);
    line-height: .95;
    color: var(--so-accent);
    font-variant-numeric: tabular-nums;
}
.so-dateline-mon {
    display: block;
    margin-top: 4px;
    font-family: var(--so-sans);
    font-size: .625rem;
    letter-spacing: .16em;
    color: var(--so-muted);
}
.so-dateline-body { display: block; }
.so-dateline-title { display: block; font-size: 1.1875rem; line-height: 1.28; }
.so-dateline-stand {
    display: block;
    margin-top: 8px;
    font-family: var(--so-serif);
    font-size: .9375rem;
    line-height: 1.55;
    color: var(--so-muted);
    max-width: 68ch;
}

/* ══════════════════════════════════════════════════════════════════════
   MODULE 5 — Visual stories scroller
   ══════════════════════════════════════════════════════════════════════ */

.so-scroller-outer { position: relative; }
.so-scroller {
    display: flex;
    gap: var(--so-gap);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    /* Start flush with the container's content edge so the first card lines up
       with the section label above it, then bleed off the right. */
    padding-inline: max(var(--so-gutter), (100vw - var(--so-container)) / 2);
    scroll-padding-inline: max(var(--so-gutter), (100vw - var(--so-container)) / 2);
    padding-bottom: 22px;
    scrollbar-width: none;
    cursor: grab;
    -webkit-overflow-scrolling: touch;
}
.so-scroller::-webkit-scrollbar { display: none; }
.so-scroller.is-dragging { cursor: grabbing; scroll-behavior: auto; scroll-snap-type: none; }
.so-scroller.is-dragging a { pointer-events: none; }

.so-vcard {
    flex: 0 0 clamp(220px, 22vw, 300px);
    scroll-snap-align: start;
    position: relative;
}
.so-vcard .so-media { aspect-ratio: 9 / 16; }
.so-vcard-cap {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    padding: 22px 20px;
    background: var(--so-scrim);
    color: #fff;
    pointer-events: none;
}
.so-vcard-cap .so-kicker { color: #fff; margin-bottom: 8px; }
.so-vcard-title {
    font-family: var(--so-serif);
    font-weight: 400;
    font-size: 1.125rem;
    line-height: 1.24;
    color: #fff;
}

.so-progress {
    height: 2px;
    background: var(--so-hair);
    position: relative;
    overflow: hidden;
}
.so-progress-bar {
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 0;
    background: var(--so-accent);
    transition: width 120ms linear;
}

/* ══════════════════════════════════════════════════════════════════════
   MODULE 6 — Longreads
   ══════════════════════════════════════════════════════════════════════ */

.so-longreads {
    border-top: 1px solid var(--so-hair);
    border-bottom: 1px solid var(--so-hair);
}
.so-longread-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: clamp(40px, 6vw, 96px);
}
.so-longread .so-media { aspect-ratio: 16 / 9; }
.so-longread .so-card-body { padding-top: 22px; }
.so-longread .so-kicker { margin-bottom: 12px; }
.so-longread-title {
    font-size: clamp(1.55rem, 2.3vw, 2.125rem);   /* 34px */
    line-height: 1.16;
}
.so-longread-excerpt {
    font-family: var(--so-serif);
    font-size: 1.0625rem;
    line-height: 1.6;
    color: var(--so-muted);
    margin-top: 16px;
    max-width: 46ch;
}
.so-readtag {
    display: inline-block;
    margin-top: 20px;
    font-family: var(--so-sans);
    font-size: .6875rem;
    font-weight: 500;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--so-accent);
}

/* ══════════════════════════════════════════════════════════════════════
   ARCHIVE (category / tag / author)
   ══════════════════════════════════════════════════════════════════════ */

.so-archive-head {
    padding-block: clamp(26px, 3.4vw, 48px) clamp(26px, 3vw, 42px);
    border-bottom: 1px solid var(--so-hair);
}
.so-crumbs {
    display: flex;
    align-items: center;
    gap: .7em;
    font-family: var(--so-sans);
    font-size: .6875rem;
    font-weight: 500;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--so-muted);
    margin-bottom: clamp(16px, 1.8vw, 26px);
}
.so-crumbs a:hover { color: var(--so-accent); }
.so-crumbs span[aria-hidden] { color: var(--so-hair); }
.so-crumbs [aria-current] { color: var(--so-ink); }

.so-archive-title {
    font-family: var(--so-serif);
    font-weight: 400;
    font-size: clamp(2.4rem, 6.4vw, 5.2rem);
    line-height: .96;
    letter-spacing: -.026em;
    color: var(--so-ink);
}
.so-archive-desc {
    margin-top: 18px;
    font-family: var(--so-serif);
    font-size: clamp(1rem, 1.2vw, 1.15rem);
    line-height: 1.6;
    color: var(--so-muted);
    max-width: 56ch;
}
.so-archive-count {
    margin-top: clamp(16px, 1.8vw, 24px);
    display: flex;
    align-items: center;
    gap: .75em;
    font-family: var(--so-sans);
    font-size: .6875rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--so-muted);
}

/* Lead story: landscape plate, copy beneath at a controlled measure */
.so-archive-lead { padding-block: clamp(30px, 4vw, 60px) 0; }
.so-archive-lead-grid { display: grid; gap: clamp(22px, 2.6vw, 38px); }
/* A full-width 16:9 plate runs ~700px tall at desktop and swamps the page.
   Cap it in px (not vh, which resizes with the window). */
.so-archive-lead-media .so-media { max-height: 540px; }
.so-archive-lead-title {
    font-size: clamp(1.7rem, 3.1vw, 2.85rem);
    line-height: 1.08;
    letter-spacing: -.02em;
    margin-top: 14px;
    text-wrap: balance;
}
.so-archive-lead-stand {
    margin-top: 16px;
    font-family: var(--so-serif);
    font-size: clamp(1rem, 1.15vw, 1.15rem);
    line-height: 1.6;
    color: var(--so-muted);
    max-width: 60ch;
}
.so-archive-lead-well .so-byline { margin-top: 18px; }

/* ── Search field ───────────────────────────────────────────────────
   One element, one hairline, no nested boxes. The old markup wrapped a
   bordered input inside a bordered shell with its own icon cell, which
   read as three stacked borders. */

.so-search {
    position: relative;
    display: flex;
    align-items: center;
    max-width: 640px;
    margin-top: clamp(22px, 2.6vw, 34px);
    border-bottom: 1px solid var(--so-ink);
    transition: border-color .2s var(--so-ease);
}
.so-search:focus-within { border-bottom-color: var(--so-accent); }

.so-search-input {
    flex: 1;
    min-width: 0;
    background: transparent;
    border: 0;
    border-radius: 0;
    padding: 12px 76px 14px 0;
    font-family: var(--so-serif);
    font-size: clamp(1.15rem, 2.2vw, 1.7rem);
    line-height: 1.3;
    color: var(--so-ink);
    appearance: none;
}
.so-search-input::placeholder { color: var(--so-muted); opacity: .7; }
.so-search-input:focus { outline: none; }
/* Chrome draws its own clear affordance on type=search; we supply our own. */
.so-search-input::-webkit-search-decoration,
.so-search-input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }

.so-search-submit,
.so-search-clear {
    position: absolute;
    display: inline-grid;
    place-items: center;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
    color: var(--so-ink);
    transition: color .2s var(--so-ease);
}
.so-search-submit { right: 0; width: 34px; height: 34px; }
.so-search-clear  { right: 42px; width: 28px; height: 28px; color: var(--so-muted); }
.so-search-submit:hover,
.so-search-clear:hover { color: var(--so-accent); }
/* An explicit `display` beats the UA stylesheet's [hidden]{display:none},
   so the clear button has to opt out of it by hand. */
.so-search-clear[hidden] { display: none; }

/* Live results */
.so-livewrap[hidden] { display: none; }
.so-livemore {
    margin-top: clamp(24px, 2.6vw, 34px);
    font-family: var(--so-sans);
    font-size: .6875rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--so-muted);
}
.so-livemore a { color: var(--so-accent); border-bottom: 1px solid currentColor; padding-bottom: 2px; }
.so-listgrid .so-card[aria-selected="true"] .so-card-title span { background-size: 100% 1px; }
.so-listgrid .so-card[aria-selected="true"] .so-media img { transform: scale(1.05); }

/* Archive grid */
.so-listgrid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 44px var(--so-gap);
}

.so-archive-empty {
    font-family: var(--so-serif);
    font-size: 1.15rem;
    line-height: 1.6;
    color: var(--so-muted);
}
.so-archive-empty a { color: var(--so-accent); text-decoration: underline; text-underline-offset: 3px; }

/* Pager */
.so-pager { padding-bottom: clamp(56px, 7vw, 104px); }
.so-pager-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    border-top: 1px solid var(--so-hair);
    padding-top: clamp(24px, 2.8vw, 36px);
}
.so-pagerbtn {
    font-family: var(--so-sans);
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--so-ink);
    border-bottom: 1px solid var(--so-hair);
    padding-bottom: .45em;
    transition: color .2s var(--so-ease), border-color .2s var(--so-ease);
}
.so-pagerbtn:hover { color: var(--so-accent); border-color: var(--so-accent); }
.so-pagerbtn.is-off { color: var(--so-hair); border-color: transparent; }
.so-pager-count {
    font-family: var(--so-sans);
    font-size: .6875rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--so-muted);
}

/* ══════════════════════════════════════════════════════════════════════
   MODULE 7 — Newsletter
   ══════════════════════════════════════════════════════════════════════ */

.so-news {
    background: var(--so-ink);
    color: var(--so-canvas);
    padding-block: clamp(64px, 8vw, 118px);
}
.so-news-inner { max-width: 620px; margin-inline: auto; text-align: center; }
.so-news-title {
    font-family: var(--so-serif);
    font-weight: 400;
    font-size: clamp(1.9rem, 3.4vw, 2.5rem);      /* 40px */
    line-height: 1.14;
    letter-spacing: -.018em;
    color: var(--so-canvas);
}
.so-news-sub {
    margin-top: 14px;
    font-family: var(--so-sans);
    font-size: .9375rem;
    line-height: 1.6;
    color: rgba(252, 251, 248, .62);
}
.so-news-form {
    position: relative;
    margin-top: 40px;
    display: flex;
    align-items: center;
}
.so-news-form input {
    flex: 1;
    width: 100%;
    background: transparent;
    border: 0;
    border-bottom: 1px solid rgba(252, 251, 248, .28);
    border-radius: 0;
    padding: 14px 44px 14px 0;
    font-family: var(--so-sans);
    font-size: .9375rem;
    letter-spacing: .02em;
    color: var(--so-canvas);
    transition: border-color 260ms var(--so-ease);
}
.so-news-form input::placeholder { color: rgba(252, 251, 248, .42); }
.so-news-form input:focus { outline: none; border-bottom-color: var(--so-accent); }
.so-news-submit {
    position: absolute;
    right: 0;
    display: inline-grid;
    place-items: center;
    width: 40px; height: 40px;
    background: none; border: 0; padding: 0;
    color: var(--so-canvas);
    cursor: pointer;
    transition: color 260ms var(--so-ease), transform 260ms var(--so-ease);
}
.so-news-submit:hover { color: var(--so-accent); transform: translateX(4px); }
.so-news-form.is-busy { opacity: .55; pointer-events: none; }

/* Sign-up outcome. Empty and inert until the script fills it, so it takes no
   vertical space on a page where nobody has submitted. */
.so-news-note {
    margin-top: 26px;
    font-family: var(--so-sans);
    font-size: .9375rem;
    line-height: 1.6;
    letter-spacing: .01em;
    color: rgba(252, 251, 248, .62);
    opacity: 0;
    transition: opacity 420ms var(--so-ease);
}
.so-news-note:empty { display: none; }
.so-news-note.is-shown { opacity: 1; }
.so-news-note.is-error { color: #E9A08C; }

/* The thank-you replaces the form, so it carries the weight the form had. */
.so-news-note.is-thanks {
    margin-top: 40px;
    font-family: var(--so-serif);
    font-size: clamp(1.05rem, 1.8vw, 1.25rem);
    line-height: 1.45;
    letter-spacing: -.005em;
    color: var(--so-canvas);
}

/* ══════════════════════════════════════════════════════════════════════
   MODULE 8 — From the archive
   ══════════════════════════════════════════════════════════════════════ */

.so-archive-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--so-gap);
}
.so-arch .so-media { aspect-ratio: 1 / 1; }
.so-arch .so-media img {
    opacity: .4;
    transition: opacity 500ms var(--so-ease), transform 500ms var(--so-ease);
}
.so-arch:hover .so-media img,
.so-arch:focus-visible .so-media img { opacity: 1; }
.so-arch-date {
    display: block;
    margin-top: 16px;
    font-family: var(--so-serif);
    font-size: 1.375rem;
    line-height: 1;
    color: var(--so-accent);
}
.so-arch-title {
    margin-top: 10px;
    font-size: 1.0625rem;
    line-height: 1.3;
}

/* ══════════════════════════════════════════════════════════════════════
   FOOTER
   ══════════════════════════════════════════════════════════════════════ */

.so-footer {
    background: var(--so-ink);
    color: var(--so-canvas);
    font-family: var(--so-sans);
}
.so-footer a { color: inherit; text-decoration: none; }
.so-footer-grid {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr 1fr;
    gap: clamp(32px, 4vw, 64px);
    padding-block: clamp(56px, 6vw, 92px);
}
/* ── Page forms (contact, story submission) ───────────────────────────── */
.so-form {
    margin-top: 56px;
    padding-top: 40px;
    border-top: 1px solid var(--so-hair);
}
.so-form-title {
    font-family: var(--so-serif);
    font-size: clamp(1.5rem, 2.4vw, 2rem);
    line-height: 1.15;
    letter-spacing: -.015em;
    color: var(--so-ink);
}
.so-form-note {
    margin-top: 10px;
    font-family: var(--so-sans);
    font-size: .9375rem;
    line-height: 1.6;
    color: var(--so-muted);
}
.so-form-body { margin-top: 28px; display: grid; gap: 20px; }
.so-form-body.is-busy { opacity: .55; pointer-events: none; }
.so-field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.so-field { display: block; }
.so-field > span {
    display: block;
    margin-bottom: 8px;
    font-family: var(--so-sans);
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--so-muted);
}
.so-field input[type=text],
.so-field input[type=email],
.so-field select,
.so-field textarea {
    width: 100%;
    background: transparent;
    border: 1px solid var(--so-hair);
    border-radius: 0;
    padding: 12px 14px;
    font-family: var(--so-sans);
    font-size: .9375rem;
    color: var(--so-ink);
    transition: border-color 260ms var(--so-ease);
}
.so-field textarea { resize: vertical; line-height: 1.65; }
.so-field input:focus,
.so-field select:focus,
.so-field textarea:focus { outline: none; border-color: var(--so-accent); }
.so-field input[type=file] {
    width: 100%;
    font-family: var(--so-sans);
    font-size: .875rem;
    color: var(--so-muted);
}
.so-field-hint {
    display: block;
    margin-top: 6px;
    font-family: var(--so-sans);
    font-size: .8125rem;
    color: var(--so-muted);
}
.so-form-submit {
    justify-self: start;
    background: var(--so-ink);
    color: var(--so-canvas);
    border: 1px solid var(--so-ink);
    border-radius: 0;
    padding: 13px 30px;
    font-family: var(--so-sans);
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    cursor: pointer;
    transition: background-color 260ms var(--so-ease), color 260ms var(--so-ease);
}
.so-form-submit:hover { background: var(--so-accent); border-color: var(--so-accent); }
.so-form-msg {
    font-family: var(--so-sans);
    font-size: .9375rem;
    line-height: 1.6;
    color: var(--so-muted);
    opacity: 0;
    transition: opacity 380ms var(--so-ease);
}
.so-form-msg:empty { display: none; }
.so-form-msg.is-shown { opacity: 1; }
.so-form-msg.is-error { color: #A3341A; }
/* Honeypot: off-screen rather than display:none, which some bots skip. */
.so-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

@media (max-width: 640px) {
    .so-field-row { grid-template-columns: 1fr; }
}

/* Sits above the wordmark. The panel is dark in both themes, so no light/dark
   swap is needed here — the layout always hands it the dark-mode mark. */
.so-footer-logo {
    display: block;
    margin-bottom: 20px;
}
.so-footer-logo img {
    height: clamp(46px, 5.2vw, 68px);
    width: auto;
    max-width: 100%;
    object-fit: contain;
}

.so-footer-mark {
    font-family: var(--so-serif);
    font-weight: 500;
    font-size: clamp(1.6rem, 2.6vw, 2.25rem);
    letter-spacing: .16em;
    text-transform: uppercase;
    line-height: 1.15;
    color: var(--so-canvas);
}
.so-footer-manifesto {
    margin-top: 18px;
    font-size: .9375rem;
    line-height: 1.6;
    color: rgba(252, 251, 248, .58);
    max-width: 34ch;
}
.so-footer h3 {
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: rgba(252, 251, 248, .5);
    margin-bottom: 20px;
}
.so-footer-links li + li { margin-top: 12px; }
.so-footer-links a {
    font-size: .9375rem;
    color: rgba(252, 251, 248, .84);
    transition: color 200ms var(--so-ease);
}
.so-footer-links a:hover { color: var(--so-accent); }

.so-social { display: flex; gap: 10px; flex-wrap: wrap; }
.so-social a {
    display: inline-grid;
    place-items: center;
    width: 38px; height: 38px;
    border: 1px solid rgba(252, 251, 248, .28);
    border-radius: 50%;
    color: rgba(252, 251, 248, .84);
    transition: border-color 220ms var(--so-ease), color 220ms var(--so-ease);
}
.so-social a:hover { border-color: var(--so-accent); color: var(--so-accent); }
.so-social a svg { display: block; }
.so-social-empty {
    font-size: .8125rem;
    line-height: 1.5;
    color: rgba(252, 251, 248, .45);
    max-width: 22ch;
}

.so-footer-bottom {
    border-top: 1px solid rgba(252, 251, 248, .16);
    padding-block: 26px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 16px 28px;
}
.so-legal { display: flex; align-items: center; flex-wrap: wrap; gap: 14px; }
.so-legal a,
.so-copy,
.so-edition select {
    font-size: .6875rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: rgba(252, 251, 248, .58);
}
.so-legal a:hover { color: var(--so-accent); }
.so-legal .so-bar { width: 1px; height: 11px; background: rgba(252, 251, 248, .28); }
.so-edition select {
    background: transparent;
    border: 1px solid rgba(252, 251, 248, .28);
    padding: 9px 12px;
    font-family: var(--so-sans);
    cursor: pointer;
}
.so-edition select option { color: #111; }

/* ══════════════════════════════════════════════════════════════════════
   BACK TO TOP
   Sits below the menu overlay (z 120) so it can never cover it.
   ══════════════════════════════════════════════════════════════════════ */

/* Spans the first screenful. While any of it is still in view we are near the
   top and the button stays hidden; once its bottom edge scrolls away the
   button appears. Height IS the threshold, which is why no rootMargin is
   needed (a negative rootMargin would push the sentinel out of the root at
   scroll 0 and invert the whole thing). */
.so-topsentinel {
    position: absolute;
    top: 0; left: 0;
    width: 1px;
    height: 320px;
    pointer-events: none;
    /* Not visibility:hidden - that would make it unfocusable, and we focus it
       after the jump. It is 1px wide and empty, so nothing shows. */
    outline: none;
}

.so-totop {
    position: fixed;
    right: clamp(16px, 2.2vw, 30px);
    bottom: clamp(16px, 2.2vw, 30px);
    z-index: 80;
    display: inline-grid;
    place-items: center;
    width: 44px;
    height: 44px;
    padding: 0;
    background: var(--so-canvas);
    border: 1px solid var(--so-hair);
    border-radius: 0;
    color: var(--so-ink);
    cursor: pointer;
    opacity: 0;
    visibility: hidden;
    transform: translateY(8px);
    transition: opacity .3s var(--so-ease),
                transform .3s var(--so-ease),
                visibility 0s linear .3s,
                background-color .2s var(--so-ease),
                border-color .2s var(--so-ease),
                color .2s var(--so-ease);
}
.so-totop.is-in {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition-delay: 0s;
}
.so-totop:hover,
.so-totop:focus-visible {
    background: var(--so-accent);
    border-color: var(--so-accent);
    color: #fff;
}
.so-totop svg { display: block; }

@media (max-width: 560px) {
    .so-totop { width: 40px; height: 40px; }
}

/* ══════════════════════════════════════════════════════════════════════
   SCROLL REVEALS
   ══════════════════════════════════════════════════════════════════════ */

/* Progressive enhancement: content is visible by default and only hidden once
   JS has confirmed it can reveal it again. Without this, a failed script or an
   observer that never fires leaves the page blank. */
.so-js .so-reveal {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity 640ms var(--so-ease), transform 640ms var(--so-ease);
}
.so-js .so-reveal.is-in { opacity: 1; transform: none; }

/* ══════════════════════════════════════════════════════════════════════
   RESPONSIVE
   ══════════════════════════════════════════════════════════════════════ */

@media (max-width: 1240px) {
    .so-lead-media .so-media,
    .so-lead.is-mirrored .so-lead-media .so-media { margin-inline: 0; }
}

@media (max-width: 1024px) {
    .so-page, .so-header, .so-menu, .so-footer { --so-gap: 24px; --so-rhythm: 76px; }
    /* Track the tablet logo height, not the desktop one. */
    .so-header, .so-menu { --so-header-h: max(78px, calc(var(--theme-logo-h-tablet, 40px) + 30px)); }
    .so-wordmark img { height: var(--theme-logo-h-tablet, 40px); }
    /* hero stays split */
    .so-carousel { --so-cols: 3.15; }   /* the part-card signals more to come */
    .so-archive-grid { grid-template-columns: repeat(3, 1fr); }
    .so-menu-body { grid-template-columns: 1fr .8fr; gap: 40px; }
    .so-footer-grid { grid-template-columns: 1.6fr 1fr 1fr; }
    .so-footer-follow { grid-column: 1 / -1; }

    .so-listgrid { grid-template-columns: repeat(3, 1fr); }
    /* Category families: soften the offsets before they get cramped. */
    .so-hang-item--1 { margin-top: 34px; }
    .so-hang-item--2 { margin-top: 14px; }
    .so-lookbook { grid-template-columns: 1fr 1fr; }
    .so-lookbook-copy { grid-column: 1 / -1; order: 3; align-self: start; }
    .so-lookbook-plate--b { margin-top: clamp(28px, 5vw, 64px); }
}

@media (max-width: 768px) {
    .so-page, .so-header, .so-menu, .so-footer {
        --so-gutter: 20px;
        --so-rhythm: 56px;
    }
    /* hero stacks image over text */
    .so-lead-grid { grid-template-columns: 1fr; gap: 26px; }
    .so-lead-media,
    .so-lead-well,
    .so-lead.is-mirrored .so-lead-media,
    .so-lead.is-mirrored .so-lead-well { grid-column: 1 / -1; order: initial; }
    .so-lead-media .so-media { aspect-ratio: 4 / 3; }
    .so-lead-well { padding-block: 0; }

    .so-carousel { --so-cols: 2.15; }
    .so-archive-grid { grid-template-columns: repeat(2, 1fr); }
    .so-longread-grid { grid-template-columns: 1fr; gap: 48px; }

    .so-listgrid { grid-template-columns: repeat(2, 1fr); gap: 36px var(--so-gap); }
    /* Category families collapse to single column, offsets reset. */
    .so-hang { grid-template-columns: 1fr 1fr; }
    .so-hang-rail { display: none; }
    .so-hang-item--1, .so-hang-item--2 { margin-top: 0; }
    .so-vitrine { grid-template-columns: 1fr; gap: 34px; padding: 32px 24px; }
    .so-vitrine-item .so-media { width: clamp(120px, 44%, 170px); }
    .so-lookbook { grid-template-columns: 1fr; }
    .so-lookbook-plate--b { margin-top: 0; }
    .so-lookbook-copy { order: initial; }
    .so-row2-link { grid-template-columns: 76px 1fr; }
    .so-row2-meta { display: none; }        /* date already sits in the byline */
    .so-swatch { grid-template-columns: 1fr; }
    .so-swatch-item { min-height: 0; }
    .so-statement-more { grid-template-columns: 1fr; }
    .so-statement-more li { padding-block: 18px; }
    .so-statement-more li + li { border-top: 1px solid var(--so-hair); }
    .so-dateline-link { grid-template-columns: 60px 1fr; }

    .so-today-inner { grid-template-columns: auto 1fr; height: 50px; }
    .so-today-rot { height: 50px; }
    .so-today-all { display: none; }
    .so-today-item a { font-size: .9375rem; }

    .so-menu-body { grid-template-columns: 1fr; }
    .so-menu-preview { display: none; }

    .so-footer-grid { grid-template-columns: 1fr 1fr; }
    .so-footer-brand { grid-column: 1 / -1; }
}

@media (max-width: 560px) {
    /* Let every header cell shrink; a fixed `1fr auto 1fr` cannot go below the
       wordmark's intrinsic width and pins the whole page wider than the screen. */
    .so-header-inner { grid-template-columns: auto minmax(0, 1fr) auto; gap: 10px; }
    .so-header-inner > * { min-width: 0; }
    .so-wordmark { overflow: hidden; }
    /* An uploaded logo must also survive the narrow grid cell. */
    .so-header, .so-menu { --so-header-h: max(78px, calc(var(--theme-logo-h-mobile, 36px) + 26px)); }
    .so-wordmark img { height: var(--theme-logo-h-mobile, 36px); max-width: 100%; }
    /* Tighter tracking buys the width to run the wordmark larger without
       truncating it or pushing the page wide. */
    .so-wordmark-text {
        font-size: clamp(1rem, 4.4vw, 1.3rem);
        letter-spacing: .1em;
        text-indent: .1em;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .so-header-right { gap: 6px; }
    .so-iconbtn { width: 26px; height: 26px; }
    .so-subscribe { padding: 7px 9px; font-size: .5625rem; letter-spacing: .06em; }
    .so-menubtn { gap: 7px; }
    .so-menubtn-label { display: none; }
    .so-menu-top .so-util { display: none; }
}

@media (max-width: 480px) {
    .so-carousel { --so-cols: 1.12; }
    .so-archive-grid { grid-template-columns: 1fr; }
    .so-listgrid { grid-template-columns: 1fr; }
    .so-hang { grid-template-columns: 1fr; }
    .so-quote { min-height: 0; padding: 32px 26px; }
    .so-footer-grid { grid-template-columns: 1fr; }
    .so-footer-bottom { flex-direction: column; align-items: flex-start; }
    /* horizontal scroller stays */
    .so-vcard { flex: 0 0 72vw; }
}

/* ══════════════════════════════════════════════════════════════════════
   DARK MODE
   Driven by html.dark, not the OS: the site loads light for everyone and
   only goes dark when the reader asks for it via the header toggle. The
   class also switches on the 100+ html.dark rules the legacy stylesheet
   already ships for the interior components.

   The ink newsletter band and footer are already dark in light mode, so
   here they invert to a lifted surface rather than staying the darkest
   thing on the page.
   ══════════════════════════════════════════════════════════════════════ */

html.dark { color-scheme: dark; }     /* native controls + scrollbars follow */

html.dark .so-body,
html.dark .so-page,
html.dark .so-header,
html.dark .so-menu,
html.dark .so-footer {
    --so-canvas: #121110;
    --so-ink:    #F2F0EC;
    --so-muted:  #9A948B;
    --so-hair:   #2E2B27;
    /* Lifted for contrast on the dark canvas. Derived from the saved accent by
       ThemeService so dark mode follows Appearance instead of staying on the
       hand-picked terracotta. */
    --so-accent: var(--theme-accent-dark, #D2714D);
    --so-accent-tint: var(--theme-accent-dark-tint, #241A16);
}
html.dark .so-media,
html.dark .so-menu-preview { background: #1E1C1A; }

/* These two blocks are ink-on-canvas in light mode; invert the relationship
   so they read as a raised surface, not a black hole. */
html.dark .so-news,
html.dark .so-footer {
    background: #1C1A18;
    color: var(--so-ink);
}
html.dark .so-news-title,
html.dark .so-footer-mark      { color: var(--so-ink); }
html.dark .so-news-sub         { color: rgba(242, 240, 236, .62); }
html.dark .so-footer-manifesto { color: rgba(242, 240, 236, .58); }
html.dark .so-footer h3        { color: rgba(242, 240, 236, .5); }
html.dark .so-footer-links a   { color: rgba(242, 240, 236, .84); }
html.dark .so-news-form input {
    color: var(--so-ink);
    border-bottom-color: rgba(242, 240, 236, .28);
}
html.dark .so-news-form input::placeholder { color: rgba(242, 240, 236, .42); }
html.dark .so-news-submit { color: var(--so-ink); }
html.dark .so-social a {
    border-color: rgba(242, 240, 236, .28);
    color: rgba(242, 240, 236, .84);
}
html.dark .so-footer-bottom { border-top-color: rgba(242, 240, 236, .16); }
html.dark .so-legal a,
html.dark .so-copy,
html.dark .so-edition select { color: rgba(242, 240, 236, .58); }
html.dark .so-edition select { border-color: rgba(242, 240, 236, .28); }
html.dark .so-edition select option { color: #121110; }
html.dark .so-legal .so-bar { background: rgba(242, 240, 236, .28); }
/* Archive thumbnails need more presence against a dark canvas. */
html.dark .so-arch .so-media img { opacity: .55; }

/* ── Theme toggle ───────────────────────────────────────────────────── */

.so-themebtn {
    display: inline-grid;
    place-items: center;
    width: 34px; height: 34px;
    padding: 0;
    background: none;
    border: 0;
    border-radius: 0;
    color: var(--so-ink);
    cursor: pointer;
    transition: color .2s var(--so-ease);
}
.so-themebtn:hover { color: var(--so-accent); }
.so-themebtn svg { display: block; }
/* Show the moon in light mode (tap to go dark) and the sun in dark mode. */
.so-themebtn .so-icon-sun  { display: none; }
html.dark .so-themebtn .so-icon-sun  { display: block; }
html.dark .so-themebtn .so-icon-moon { display: none; }

/* ══════════════════════════════════════════════════════════════════════
   REDUCED MOTION — disable all transforms and reveals
   ══════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
    .so-page *,
    .so-header *,
    .so-menu *,
    .so-footer * {
        transition-duration: .01ms !important;
        animation-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
    .so-reveal { opacity: 1 !important; transform: none !important; }
    .so-seclabel .so-rule { transform: scaleX(1) !important; }
    .so-cardlink:hover .so-media img,
    .so-arch:hover .so-media img { transform: none !important; }
    .so-header.is-hidden { transform: none !important; }
    .so-header.is-shrunk .so-wordmark { transform: none !important; }
    .so-scroller { scroll-behavior: auto !important; }
}
