/* ==========================================================================
   Syson Travel — site stylesheet
   Single handcrafted sheet. No build step, no framework.

   Design notes
   - Palette is grounded in Kisoro and the Virungas: canopy green, volcanic
     ash, murram-road red, golden-monkey ochre. Not safari khaki.
   - One bold move only: the Virunga ridge line (a masked SVG) that closes
     every dark band and divides the light ones. Everything else stays quiet.
   - Every colour, size, space and radius is a custom property in :root.
     Nothing below this block hard-codes a hex value.
   - Mobile first. Media queries only add complexity upward.
   ========================================================================== */

:root {
    /* --- Colour ---------------------------------------------------------
       ink      forest floor at dusk — body text, deepest ground
       canopy   Bwindi canopy — header, footer, dark bands
       ash      volcanic ash from the Virungas — the page ground
       murram   the red laterite road into Kisoro — the single accent
       gold     golden monkey — small marks, dark grounds only          */
    --ink: #101a15;
    --canopy: #1b3a2b;
    --ash: #f7f5f0;
    --ash-deep: #eeeae1;
    --ash-line: #d9d8cf;
    --surface: #ffffff;
    --slate: #54615a;
    --murram: #a83b18;
    --murram-deep: #822c0f;
    --gold: #d9a441;

    /* Roles */
    --bg: var(--ash);
    --text: var(--ink);
    --text-muted: var(--slate);
    --accent: var(--murram);
    --accent-hover: var(--murram-deep);
    --rule: var(--ash-line);
    --rule-strong: #6e7a73;
    --focus: var(--murram);

    /* On dark bands */
    --on-dark: #ffffff;
    --on-dark-muted: #c3d0c7;
    --rule-dark: #6d8879;

    /* Two roles that used to read a raw palette value directly. Both mean
       "the opposite end of the scale from the page ground", so both have to
       flip with the theme rather than staying literally light or literally
       ink. See the [data-theme="dark"] block. */
    --button-light-bg: var(--ash);
    --button-light-text: var(--ink);
    --card-hover-border: var(--ink);

    /* Third-party brand marks. These are the platforms' own colours, not
       the Syson palette, and are used nowhere except .social-link. X and
       TikTok are black by their own brand guidance; the ring keeps their
       edge visible against the canopy footer. */
    --brand-x: #000000;
    --brand-instagram: #e4405f;
    --brand-facebook: #1877f2;
    --brand-tiktok: #000000;
    --brand-youtube: #ff0000;

    /* Feedback */
    --danger: #97290f;
    --danger-bg: #fbeae5;
    --ok: #1b5e3a;
    --ok-bg: #e2efe7;

    /* --- Type -----------------------------------------------------------
       Source Sans 3 gives headings and body copy a clean, consistent voice.
       Both fall back to stacks that hold the layout if the webfont never
       arrives, because the fonts load asynchronously.                   */
    --font-display: var(--font-text);
    --font-text: "Source Sans 3", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

    /* --- Type scale ------------------------------------------------------
       One scale, and every heading in the sheet resolves to it.
       step-4 is the page h1 and the largest thing on any page; step-3 is a
       section h2. Nothing sets a font size that is not one of these.     */
    --step--2: clamp(0.75rem, 0.73rem + 0.09vw, 0.8rem);
    --step--1: clamp(0.85rem, 0.83rem + 0.12vw, 0.92rem);
    --step-0: clamp(1rem, 0.97rem + 0.16vw, 1.09rem);
    --step-1: clamp(1.125rem, 0.5vw + 1rem, 1.25rem);
    --step-2: clamp(1.25rem, 1vw + 1rem, 1.5rem);
    --step-3: clamp(1.5rem, 1.5vw + 1rem, 2rem);
    --step-4: clamp(2rem, 3vw + 1rem, 2.75rem);

    /* Line height falls as size rises: display type wants ~1.1, body ~1.5. */
    --lh-tight: 1.1;
    --lh-snug: 1.2;
    --lh-body: 1.7;
    /* Measures. Seven governed caps replace fourteen ad-hoc ch values.
       --measure-wide is a reading column, not a container: it caps line
       length while leaving the block flush to the shared container edge. */
    --measure-wide: 52rem;
    --measure: 65ch;
    --measure-lede: 52ch;
    --measure-tight: 42ch;
    --measure-note: 36ch;
    --measure-head: 20ch;
    --measure-display: 14ch;

    /* --- Space -----------------------------------------------------------
       One geometric scale. Every margin, padding and gap in this sheet
       resolves to one of these; only the three fluid values scale with the
       viewport, so spacing never jumps at a breakpoint.

       Grouping is carried by the scale, not by even distribution:
         16  inside a block (heading to its own paragraph)
         32  between blocks in a section (a section head to its content)
         section-y  between sections
       If those three are equal, nothing reads as grouped.              */
    --space-4: 0.25rem;
    --space-8: 0.5rem;
    --space-12: 0.75rem;
    --space-16: 1rem;
    --space-24: 1.5rem;
    --space-32: 2rem;
    --space-48: 3rem;
    --space-64: 4rem;
    --space-96: 6rem;

    /* Section rhythm. A section pays HALF of this on each edge, so any two
       adjacent sections produce exactly one --section-y between them and
       never two. Padding does not collapse; halving is what replaces it. */
    --section-y: clamp(4rem, 9vw, 8rem);
    --section-y-tight: clamp(3rem, 7vw, 6rem);

    /* One container. 90% of the viewport, capped so a line of text does not
       stretch on a very wide monitor. The 90% is the gutter: 10% of 320px is
       32px, so content never touches the edge on the narrowest phone. Prose
       inside is capped separately by the --measure-* tokens below. */
    --container-w: 90%;
    --container-max: 80rem;
    /* The distance from the viewport edge to the container edge. Written
       once here; because custom properties substitute textually, the 100%
       resolves against whichever element uses it, so a full-bleed block can
       pull one edge back onto the shared container line. */
    --shell-inset: calc((100% - min(var(--container-w), var(--container-max))) / 2);

    /* --- Shape and motion ------------------------------------------------ */
    --r-xs: 2px;
    --r-sm: 10px;
    --r-pill: 999px;
    --tap: 44px;
    --ridge-h: 22px;
    --lift: 0 18px 44px -24px rgba(16, 26, 21, 0.55);
    --ease: 160ms cubic-bezier(0.2, 0, 0.2, 1);

    /* The Virunga ridge, as a mask. Colour comes from the element, so the
       same shape works on light grounds and dark ones. */
    --ridge-solid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 24'%3E%3Cpath fill='%23fff' d='M0 0h240v14l-24 10-24-13-24 10-24-12-24 11-24-8-24 10-24-9-24 9z'/%3E%3C/svg%3E");
    --ridge-line: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 24'%3E%3Cpath fill='none' stroke='%23fff' stroke-width='2' stroke-linejoin='round' d='M0 14 24 5l24 9 24-9 24 8 24-11 24 12 24-10 24 13 24-10'/%3E%3C/svg%3E");
}

/* ==========================================================================
   Dark theme

   One block, and it only re-points the palette — no rule below is duplicated
   for dark. That works because every colour in this sheet already resolves
   through a named token; where two rules still read a raw palette value for
   its lightness (.button-light, .card:hover) they were given roles above.

   The attribute is written by partials/theme-init.html before the first
   paint, from the saved preference or, failing that, the device setting.
   "System" is resolved to a concrete value there rather than by a
   prefers-color-scheme query here, so this block is never written twice.

   Palette: the same Kisoro greens, read at night. The page ground is a
   near-black green rather than pure black; canopy stays visibly green so a
   dark band still separates from the ground it sits on.
   ========================================================================== */

[data-theme="dark"] {
    color-scheme: dark;

    /* Grounds, darkest first: ink (deep bands, topbar) < page < surface. */
    --ink: #0a0f0c;
    --canopy: #173324;
    --ash: #0f1412;
    --ash-deep: #1e2622;
    --ash-line: #2c3631;
    --surface: #1a211d;

    /* Text. --slate carries muted copy and clears 7:1 on the page ground. */
    --slate: #9aa8a0;

    /* The murram accent, split by job: the darker value stays a button
       ground that white type can sit on at 5:1, the brighter one is the
       accent as *text* on a dark ground. In the light theme one value does
       both, because there white type and a light ground pull the same way. */
    --murram: #b8451c;
    --murram-deep: #c2491c;
    --gold: #e5b45c;

    /* Roles */
    --text: #e9eeea;
    --accent: #e0673c;
    --accent-hover: #f08055;
    --rule-strong: #63726a;
    --rule-dark: #46574c;
    --focus: #e0673c;

    --button-light-bg: #e9eeea;
    --button-light-text: var(--ink);
    --card-hover-border: #8b9a91;

    /* Feedback. Tinted grounds, not the light theme's pale washes. */
    --danger: #f08a6a;
    --danger-bg: #2a1712;
    --ok: #7fd3a3;
    --ok-bg: #12241a;

    /* A shadow only reads on a dark ground if it is close to black. */
    --lift: 0 18px 44px -20px rgba(0, 0, 0, 0.85);
}

/* ==========================================================================
   Reset and base
   ========================================================================== */

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

html {
    /* Native controls, scrollbars and form widgets follow this, so a dark
       page does not get a white scrollbar and a light <select> drop-down. */
    color-scheme: light;
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
}

/* Nothing may push the page wider than the viewport. */
html, body { overflow-x: clip; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-text);
    font-size: var(--step-0);
    line-height: var(--lh-body);
    -webkit-font-smoothing: antialiased;
    overflow-wrap: break-word;
}

h1, h2, h3, h4 {
    margin: 0 0 var(--space-16);
    font-family: var(--font-display);
    font-weight: 600;
    line-height: var(--lh-snug);
    letter-spacing: -0.015em;
    text-wrap: pretty;
}

h1 { font-size: var(--step-4); line-height: var(--lh-tight); letter-spacing: -0.025em; }
h2 { font-size: var(--step-3); line-height: var(--lh-snug); letter-spacing: -0.02em; }
h3 { font-size: var(--step-2); }
h4 { font-size: var(--step-1); }

p { max-width: var(--measure); margin: 0 0 var(--space-16); }
p:last-child { margin-bottom: 0; }

a { color: inherit; text-underline-offset: 0.22em; }

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

ul, ol { margin: 0 0 var(--space-16); padding-left: var(--space-16); }

button { font: inherit; color: inherit; }

::selection { background: var(--gold); color: var(--ink); }

/* --- Focus ---------------------------------------------------------------
   Never removed, only redesigned. --focus is re-declared on dark grounds so
   the ring stays visible against whatever it sits on. */
:focus-visible {
    outline: 3px solid var(--focus);
    outline-offset: 3px;
    border-radius: var(--r-xs);
}

.skip-link {
    position: absolute;
    top: var(--space-8);
    left: var(--space-8);
    z-index: 100;
    padding: var(--space-12) var(--space-16);
    border-radius: var(--r-sm);
    background: var(--ink);
    color: var(--on-dark);
    font-weight: 600;
    text-decoration: none;
    transform: translateY(-200%);
    transition: transform var(--ease);
}
.skip-link:focus-visible { transform: translateY(0); }

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ==========================================================================
   Layout primitives
   ========================================================================== */

.shell {
    width: min(var(--container-w), var(--container-max));
    margin-inline: auto;
}

main { scroll-margin-top: var(--space-32); }

/* A reading column. Caps line length, but stays flush to the container's
   left edge instead of centring on its own — one edge per page, not two. */
.reading > * { max-width: var(--measure-wide); }
.reading > * + * { margin-block-start: var(--space-32); }

/* Sections own their vertical space, and pay half of it per edge. See
   --section-y. Nothing inside a section adds to a section boundary. */
.section { padding-block: calc(var(--section-y) / 2); }
.section--tight { padding-block: calc(var(--section-y-tight) / 2); }

/* --- Flow ----------------------------------------------------------------
   Space between sibling blocks comes from one rule keyed on adjacency, so
   no module carries a top margin of its own and no boundary is paid twice.
   Overrides below tighten specific relationships; nothing loosens them. */
:is(h2, h3, p, figure, .ridge-rule, .section-head, .prose, .split) + :is(.card-grid,
.statements, .notes, .voices, .service-set, .steps, .empty-state, .ruled-list,
.faq-list, .split, .ways, .detail-layout, .contact-details, .gallery) { margin-block-start: var(--space-32); }

/* The services list is the page's main body, not another block inside the
   intro, so it takes the wider of the two grouping tiers. */
.prose + .service-set { margin-block-start: var(--space-48); }

.detail-copy > * + * { margin-block-start: var(--space-32); }
/* A heading belongs to what follows it, so it sits at the tighter tier. */
.detail-copy > :is(h2, h3) + * { margin-block-start: var(--space-16); }

/* Section padding is the only thing that sets a section boundary: padded
   containers zero the outer margins of their own first and last children. */
:is(.shell, .reading, .card-body, .detail-copy, .detail-aside, .form-card,
.empty-state, .split-copy, .prose) > :first-child { margin-block-start: 0; }
:is(.shell, .reading, .card-body, .detail-copy, .detail-aside, .form-card,
.empty-state, .split-copy, .prose) > :last-child { margin-block-end: 0; }

/* Dark bands re-point the colour roles instead of overriding every rule. */
.band-dark {
    --text: var(--on-dark);
    --text-muted: var(--on-dark-muted);
    --rule: var(--rule-dark);
    --accent: var(--gold);
    --accent-hover: var(--on-dark);
    --focus: var(--gold);
    background: var(--canopy);
    color: var(--text);
}

/* The header is canopy. A band sitting directly beneath it takes the deeper
   ink ground instead, so the two never read as one continuous slab of colour
   and the header keeps a visible bottom edge. Pairs with .ridge--deep. */
.band-deep { background: var(--ink); }

/* --- The signature: the Virunga ridge ------------------------------------ */
.ridge {
    height: var(--ridge-h);
    background-color: currentColor;
    -webkit-mask: var(--ridge-solid) repeat-x top center / 240px var(--ridge-h);
    mask: var(--ridge-solid) repeat-x top center / 240px var(--ridge-h);
}
.ridge--canopy { color: var(--canopy); }
.ridge--deep { color: var(--ink); }
/* Closes a band from below, pointing up into the section that follows. */
.ridge--flip { transform: scaleY(-1); }

/* Ridge as a divider inside light content: a drawn line, not a silhouette. */
.ridge-rule {
    height: var(--ridge-h);
    margin-block: 0 var(--space-32);
    background-color: var(--ash-line);
    -webkit-mask: var(--ridge-line) repeat-x center / 240px var(--ridge-h);
    mask: var(--ridge-line) repeat-x center / 240px var(--ridge-h);
}

/* A short ridge tick that marks a standfirst. */
.ridge-tick {
    width: 76px;
    height: 14px;
    margin-bottom: var(--space-16);
    background-color: var(--accent);
    -webkit-mask: var(--ridge-line) no-repeat left center / 240px 24px;
    mask: var(--ridge-line) no-repeat left center / 240px 24px;
}

/* --- Text helpers -------------------------------------------------------- */
.lede {
    max-width: var(--measure-lede);
    color: var(--text-muted);
    font-size: var(--step-1);
    line-height: 1.5;
}

.prose { max-width: var(--measure); color: var(--text-muted); }
.prose p { margin-bottom: var(--space-24); }
.prose a { color: var(--accent); }
.prose :is(h2, h3, h4) { color: var(--text); margin-block: var(--space-32) var(--space-12); }
.prose li + li { margin-top: var(--space-8); }

.muted { color: var(--text-muted); }

/* ==========================================================================
   Header and navigation
   ========================================================================== */

.site-topbar {
    --focus: var(--gold);
    background: var(--ink);
    color: var(--on-dark-muted);
    font-size: var(--step--2);
}
.site-topbar-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-8) var(--space-24);
    min-height: 38px;
    padding-block: var(--space-8);
}
.site-topbar a { display: inline-flex; align-items: center; min-height: var(--tap); color: var(--on-dark); text-decoration: none; }
.site-topbar a:hover { text-decoration: underline; }
.topbar-contact {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-8) var(--space-24);
}

/* --- Colour theme switch -------------------------------------------------
   Sits in the topbar, not the sticky header: it is a set-once preference,
   not navigation, and the header bar has no room for it at 320px beside the
   logo and the menu button.

   Hidden until theme-init.html has run, so a page with JavaScript blocked
   never shows a control that cannot do anything. */
.theme-switch { display: none; }
.has-theme-js .theme-switch {
    display: inline-flex;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-4);
    border: 1px solid var(--rule-dark);
    border-radius: var(--r-pill);
}
.theme-switch button {
    position: relative;
    display: grid;
    place-items: center;
    width: 34px;
    height: 28px;
    padding: 0;
    border: 0;
    border-radius: var(--r-pill);
    background: transparent;
    color: var(--on-dark-muted);
    cursor: pointer;
    transition: background-color var(--ease), color var(--ease);
}
/* The visible pill is 34x28 so the topbar stays a strip. The hit area is
   extended to the full 44px vertically by a pseudo-element — vertically
   only, because widening it here would overlap the neighbouring button and
   the last one in the row would swallow the edges of its siblings.
   Width is handled by the pointer query below instead. */
.theme-switch button::after {
    position: absolute;
    top: 50%;
    left: 0;
    width: 100%;
    height: var(--tap);
    transform: translateY(-50%);
    content: "";
}
/* A finger, not a cursor: give each button the full 44px width. Three of
   them plus the padding is 140px, which still fits the topbar's second
   line at 320px. */
@media (pointer: coarse) {
    .theme-switch button { width: var(--tap); }
}
.theme-switch button:hover { color: var(--on-dark); }
.theme-switch button[aria-pressed="true"] {
    background: var(--canopy);
    color: var(--gold);
}
.theme-icon { width: 16px; height: 16px; }

.site-header {
    --focus: var(--gold);
    position: sticky;
    top: 0;
    z-index: 40;
    border-bottom: 1px solid var(--rule-dark);
    background: var(--canopy);
    color: var(--on-dark);
}
.nav-wrap {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-16);
    min-height: 64px;
}
.site-logo-link { flex: 0 0 auto; }
.site-logo { width: clamp(112px, 22vw, 152px); height: auto; }

.nav-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--space-8);
    min-height: var(--tap);
    padding-inline: var(--space-12);
    border: 1px solid var(--rule-dark);
    border-radius: var(--r-sm);
    background: transparent;
    font-size: var(--step--1);
    font-weight: 600;
    cursor: pointer;
}
.nav-toggle-icon {
    display: inline-flex;
    flex-direction: column;
    justify-content: center;
    gap: var(--space-4);
    width: 18px;
    height: 14px;
}
.nav-toggle-icon i {
    display: block;
    height: 2px;
    background: currentColor;
    transition: transform var(--ease);
}
.nav-toggle[aria-expanded="true"] .nav-toggle-icon i:first-child { transform: translateY(3px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-icon i:last-child { transform: translateY(-3px) rotate(-45deg); }

/* Narrow viewports: the nav is a panel below the bar. It is hidden with the
   [hidden] attribute, which the script sets on load, so with JavaScript off
   the nav stays open and usable rather than disappearing. */
.site-nav {
    position: absolute;
    top: 100%;
    right: 0;
    left: 0;
    max-height: calc(100dvh - 64px);
    /* Aligned to .shell, so the panel's links sit on the same left edge
       as the logo above them rather than on a gutter of their own. */
    padding-block: var(--space-8) var(--space-24);
    padding-inline: var(--shell-inset);
    overflow-y: auto;
    border-top: 1px solid var(--rule-dark);
    background: var(--canopy);
}
.site-nav[hidden] { display: none; }
.site-nav ul {
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0;
    list-style: none;
}
.site-nav a {
    display: flex;
    align-items: center;
    min-height: var(--tap);
    padding-block: var(--space-8);
    border-bottom: 1px solid var(--rule-dark);
    color: var(--on-dark);
    font-weight: 500;
    text-decoration: none;
}
.site-nav a[aria-current="page"] { color: var(--gold); }
.site-nav a:hover { text-decoration: underline; }
.site-nav .nav-cta { border-bottom: 0; }
body.nav-open { overflow: hidden; }

/* ==========================================================================
   Buttons and links
   ========================================================================== */

.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--tap);
    padding: var(--space-12) var(--space-24);
    border: 2px solid transparent;
    border-radius: var(--r-sm);
    font-size: var(--step--1);
    font-weight: 600;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--ease), border-color var(--ease), color var(--ease);
}
.button-primary { border-color: var(--murram); background: var(--murram); color: var(--on-dark); }
.button-primary:hover { border-color: var(--murram-deep); background: var(--murram-deep); }

.button-light { border-color: var(--button-light-bg); background: var(--button-light-bg); color: var(--button-light-text); }
.button-light:hover { border-color: var(--on-dark); background: var(--on-dark); }

.button-outline { border-color: currentColor; background: transparent; color: var(--text); }
.button-outline:hover { background: var(--text); color: var(--bg); }
.band-dark .button-outline:hover { background: var(--on-dark); color: var(--canopy); }

.button-block { width: 100%; }

.button-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-12);
    margin-block: var(--space-24);
}

/* An in-flow link that reads as a link: underlined, never an arrow glyph. */
.text-link {
    display: inline-block;
    color: var(--accent);
    font-weight: 600;
    text-decoration: underline;
    text-decoration-thickness: 1px;
}
.text-link:hover { color: var(--accent-hover); text-decoration-thickness: 2px; }

.nav-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--tap);
    margin-top: var(--space-12);
    padding-inline: var(--space-24);
    border-radius: var(--r-sm);
    background: var(--murram);
    color: var(--on-dark);
    font-weight: 600;
    text-decoration: none;
    transition: background-color var(--ease);
}
.nav-cta:hover { background: var(--murram-deep); text-decoration: none; }

.back-link {
    display: inline-block;
    margin-bottom: var(--space-16);
    color: var(--text-muted);
    font-size: var(--step--1);
    font-weight: 600;
    text-decoration: underline;
}
.back-link:hover { color: var(--accent); }

/* ==========================================================================
   Page header — typographic, on the canopy band. No photo, no scrim.
   ========================================================================== */

.page-head { padding-block: var(--section-y-tight); }
.page-head h1 { max-width: var(--measure-head); margin-bottom: var(--space-16); }

/* ==========================================================================
   Home hero — asymmetric split. Type sits on solid colour so contrast is
   guaranteed at every width; the photograph is shown undarkened.
   ========================================================================== */

.hero-inner { display: grid; padding-inline: 0; }
.hero-copy { padding: var(--space-32) var(--shell-inset); }
.hero-copy h1 { max-width: var(--measure-display); margin-bottom: var(--space-24); }
.hero-copy h1 em {
    display: block;
    color: var(--gold);
    font-style: italic;
    font-weight: 600;
}
.hero-copy .lede { max-width: var(--measure-tight); }
.hero-place { margin-top: var(--space-32); color: var(--on-dark-muted); font-size: var(--step--1); }

.hero-figure { position: relative; height: 100%; margin: 0; }
.hero-figure img {
    width: 100%;
    height: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    object-position: center 35%;
}
.hero-figure figcaption {
    position: absolute;
    right: 0;
    bottom: 0;
    max-width: 70%;
    padding: var(--space-8) var(--space-16);
    background: var(--ink);
    color: var(--on-dark-muted);
    font-size: var(--step--2);
}

/* ==========================================================================
   Home: ways in. One lead panel, then a ruled list — deliberately not four
   identical tiles, and deliberately unnumbered, because it is not a sequence.
   ========================================================================== */

.ways { display: grid; gap: var(--space-32); }

.way-lead {
    --focus: var(--gold);
    position: relative;
    display: block;
    overflow: hidden;
    border-radius: var(--r-sm);
    background: var(--canopy);
    color: var(--on-dark);
    text-decoration: none;
}
.way-lead img {
    width: 100%;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    opacity: 0.75;
    transition: opacity var(--ease);
}
.way-lead:hover img { opacity: 0.92; }
.way-lead-body {
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    padding: var(--space-32) var(--space-24) var(--space-16);
    background: linear-gradient(to top, var(--ink), transparent);
}
.way-lead h3 { margin-bottom: var(--space-4); }
.way-lead p { max-width: var(--measure-note); margin: 0; color: var(--on-dark-muted); font-size: var(--step--1); }
.way-lead:hover h3 { text-decoration: underline; }

.way-list { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--rule); }
.way-list li { border-bottom: 1px solid var(--rule); }
.way-list a { display: block; min-height: var(--tap); padding-block: var(--space-24); text-decoration: none; }
.way-list h3 { margin-bottom: var(--space-4); }
.way-list a:hover h3 { color: var(--accent); text-decoration: underline; }
.way-list p { max-width: var(--measure-note); margin: 0; color: var(--text-muted); font-size: var(--step--1); }

/* The card is the link, so the cue is a span, not a nested anchor. It names
   the destination — never "learn more" — and underlines with its parent. */
.way-cue {
    display: inline-block;
    margin-top: var(--space-8);
    color: var(--accent);
    font-size: var(--step--1);
    font-weight: 600;
}
.way-lead .way-cue { color: var(--gold); }
a:hover .way-cue { text-decoration: underline; }

/* ==========================================================================
   Split (image beside copy)
   ========================================================================== */

.split { display: grid; gap: var(--space-32); align-items: start; }
.split-media { margin: 0; }
.split-media img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: var(--r-sm);
    background: var(--ash-deep);
}
.split-copy > :last-child { margin-bottom: 0; }

/* ==========================================================================
   Content cards — flat, hairline, no drop shadow, no hover lift
   ========================================================================== */

/* auto-fit, not auto-fill: an empty track left at the end of a row is what
   made short rows read as unresolved. Cards stretch to equal height. */
.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
    gap: var(--space-24);
    align-items: stretch;
}
/* ...but one card alone should not stretch across the whole container. */
.card-grid:has(> :only-child) { grid-template-columns: minmax(0, 34rem); }

.card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid var(--rule-strong);
    border-radius: var(--r-sm);
    background: var(--surface);
    transition: border-color var(--ease);
}
.card:hover { border-color: var(--card-hover-border); }
.card-media {
    width: 100%;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    background: var(--ash-deep);
}
/* Shown when a record has no image at all, so the layout never collapses. */
.card-media--empty {
    display: grid;
    place-items: center;
    padding: var(--space-16);
    color: var(--slate);
    font-size: var(--step--2);
    text-align: center;
}
.card-body { display: flex; flex: 1; flex-direction: column; padding: var(--space-32) var(--space-24); }
.card h3 { margin-bottom: var(--space-12); }
.card h3 a { color: inherit; text-decoration: none; }
.card h3 a:hover { color: var(--accent); text-decoration: underline; }
.card p { color: var(--text-muted); font-size: var(--step--1); }
.card .text-link { align-self: flex-start; margin-top: auto; }

/* Meta pairs separated by a rule, not a middle dot. */
.meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-8) var(--space-16);
    margin: 0 0 var(--space-12);
    padding: 0;
    list-style: none;
    color: var(--text-muted);
    font-size: var(--step--2);
    font-weight: 600;
}
.meta li + li { padding-left: var(--space-16); border-left: 1px solid var(--rule); }

/* The single owner of the gap between a section head and its content. */
.section-head { margin-bottom: var(--space-48); }
.section-head h2 { max-width: var(--measure-head); }
.section-foot { margin-top: var(--space-32); }

/* ==========================================================================
   Statements, ruled lists and steps
   ========================================================================== */

.statements {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
    gap: var(--space-24) var(--space-32);
    align-items: start;
    margin: 0;
    padding: 0;
    list-style: none;
}
.statements li { padding-top: var(--space-16); border-top: 2px solid var(--accent); }
.statements h3 { margin-bottom: var(--space-8); font-size: var(--step-1); }
.statements p { margin: 0; color: var(--text-muted); font-size: var(--step--1); }

/* Notes: the quieter sibling of .statements, for longer lists that carry
   reading rather than assertion — the four Uganda experiences and the eight
   services on the home page. A hairline rule instead of the accent bar, so a
   page can hold both without the two reading as the same claim twice. */
.notes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
    gap: var(--space-24) var(--space-32);
    align-items: start;
    margin: 0;
    padding: 0;
    list-style: none;
}
.notes li { padding-top: var(--space-12); border-top: 1px solid var(--rule); }
.notes h3 { margin-bottom: var(--space-8); font-size: var(--step-1); }
.notes p { margin: 0; color: var(--text-muted); font-size: var(--step--1); }

/* With a photograph on top, the hairline moves from the top of the item to
   the top of the heading, so the picture and the words it belongs to still
   read as one block and the rule still divides the row. */
.notes--figured li { padding-top: 0; border-top: 0; }
.notes--figured img {
    width: 100%;
    aspect-ratio: 3 / 2;
    margin-bottom: var(--space-16);
    object-fit: cover;
    border-radius: var(--r-sm);
    background: var(--ash-deep);
}
.notes--figured h3 { padding-top: var(--space-12); border-top: 1px solid var(--rule); }

/* The things travellers actually open with. Set as display type, because
   they are the visitor's own words and the whole point of the section is
   that one sentence is enough to start. */
.voices {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-12) var(--space-24);
    margin: 0;
    padding: 0;
    list-style: none;
}
.voices li {
    padding: var(--space-12) var(--space-16);
    border-left: 2px solid var(--accent);
    background: var(--surface);
    font-family: var(--font-display);
    font-size: var(--step-1);
    line-height: var(--lh-snug);
}
.voices-foot { max-width: var(--measure); margin-block: var(--space-32) 0; color: var(--text-muted); }

.ruled-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
    gap: 0 var(--space-32);
    align-items: start;
    margin: 0;
    padding: 0;
    list-style: none;
    border-top: 1px solid var(--rule);
}
.ruled-list li {
    padding-block: var(--space-12);
    border-bottom: 1px solid var(--rule);
    font-size: var(--step--1);
}

/* Numbers appear here and nowhere else, because this is a real sequence. */
.steps { margin: 0; padding: 0; list-style: none; counter-reset: step; }
.steps li {
    display: grid;
    grid-template-columns: 2.25rem 1fr;
    gap: var(--space-16);
    padding-block: var(--space-16);
    border-top: 1px solid var(--rule);
    counter-increment: step;
}
.steps li::before {
    content: counter(step);
    color: var(--accent);
    font-family: var(--font-display);
    font-size: var(--step-2);
    line-height: 1.1;
}
.steps h3 { margin-bottom: var(--space-4); font-size: var(--step-1); }
.steps p { margin: 0; color: var(--text-muted); font-size: var(--step--1); }

/* ==========================================================================
   Services

   Six entries, each long enough to be its own read. One decision carries the
   layout: a split inside each entry, so the argument for a service and the
   list of what it covers are scanned separately rather than as one wall of
   text.
   ========================================================================== */

.service-set { display: grid; gap: var(--space-48); counter-reset: service; }

.service-detail {
    display: grid;
    gap: var(--space-24);
    padding-top: var(--space-24);
    border-top: 2px solid var(--accent);
    counter-increment: service;
    /* The ids are link targets from elsewhere on the site, so an entry
       arrived at directly clears the sticky header. Matches .nav-wrap. */
    scroll-margin-top: calc(76px + var(--space-24));
}
/* The number marks the entry rather than occupying a column of its own:
   the two columns here are the argument and the list. */
.service-detail h3::before {
    display: block;
    margin-bottom: var(--space-8);
    color: var(--accent);
    content: counter(service, decimal-leading-zero);
    font-family: var(--font-display);
    font-size: var(--step--1);
    letter-spacing: 0.08em;
}
.service-copy > * + * { margin-block-start: var(--space-16); }
/* These six links are the page's actual calls to action, so each one gets a
   full tap target rather than the bare height of a line of text. */
.service-copy .text-link { display: inline-flex; align-items: center; min-height: var(--tap); }

/* The closing line of an entry: a qualification, not a new point. */
.service-note {
    padding-left: var(--space-16);
    border-left: 2px solid var(--rule);
    color: var(--text-muted);
    font-size: var(--step--1);
}

/* The label that introduces a list. Not a heading: it has no content of
   its own and would only add noise to the outline. The list belongs to it,
   so the pair sits at the tighter tier than the flow rule would give. */
.service-cue + :is(.tick-list, .tag-list) { margin-block-start: var(--space-12); }
.service-cue {
    margin-bottom: 0;
    color: var(--text-muted);
    font-size: var(--step--2);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* Short items that are a set, not a sequence — wrapped rather than stacked,
   because eleven one-line rows read as a much longer list than they are. */
.tag-list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-8);
    margin: 0;
    padding: 0;
    list-style: none;
}
.tag-list li {
    padding: var(--space-8) var(--space-12);
    border: 1px solid var(--rule);
    border-radius: var(--r-sm);
    background: var(--surface);
    color: var(--text-muted);
    font-size: var(--step--1);
}

/* ==========================================================================
   Empty states — an invitation, not an apology
   ========================================================================== */

.empty-state {
    padding: var(--space-48) var(--space-24);
    border: 1px dashed var(--rule-strong);
    border-radius: var(--r-sm);
    text-align: center;
}
.empty-state h3 { margin-bottom: var(--space-12); }
.empty-state p { max-width: var(--measure-tight); margin-inline: auto; color: var(--text-muted); }
.empty-state .button { margin-top: var(--space-24); }

/* ==========================================================================
   Detail pages — title on the light ground, photograph undarkened below it
   ========================================================================== */

.detail-head { padding-block: var(--section-y-tight) var(--space-32); }
.detail-head h1 { max-width: var(--measure-head); margin-bottom: var(--space-16); }

.detail-figure { margin: 0; }
.detail-figure img {
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    border-radius: var(--r-sm);
    background: var(--ash-deep);
}

.detail-layout { display: grid; gap: var(--space-48); align-items: start; }

.detail-aside {
    padding: var(--space-24);
    border: 1px solid var(--rule-strong);
    border-radius: var(--r-sm);
    background: var(--surface);
}
.detail-aside h2 { margin-bottom: var(--space-12); font-size: var(--step-1); }
.detail-aside .button { margin-top: var(--space-24); }

.related-list { margin: 0 0 var(--space-16); padding: 0; list-style: none; }
.related-list li { border-top: 1px solid var(--rule); }
.related-list a {
    display: flex;
    align-items: center;
    min-height: var(--tap);
    padding-block: var(--space-8);
    font-weight: 600;
    text-decoration: none;
}
.related-list a:hover { color: var(--accent); text-decoration: underline; }

.tick-list { margin: 0; padding: 0; list-style: none; }
.tick-list li {
    position: relative;
    padding: var(--space-12) 0 var(--space-12) var(--space-24);
    border-top: 1px solid var(--rule);
    color: var(--text-muted);
}
.tick-list li::before {
    position: absolute;
    top: 1.5em;
    left: 0;
    width: 14px;
    height: 2px;
    background: var(--accent);
    content: "";
}

.article-intro {
    max-width: var(--measure);
    margin: 0;
    font-family: var(--font-display);
    font-size: var(--step-2);
    line-height: 1.4;
}

/* ==========================================================================
   Gallery
   ========================================================================== */

.gallery { margin: 0; }
.gallery-stage {
    position: relative;
    overflow: hidden;
    border-radius: var(--r-sm);
    background: var(--ink);
}
.gallery-image {
    display: none;
    width: 100%;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    transform-origin: center;
    transition: transform var(--ease);
}
.gallery-image.is-active { display: block; }
.gallery-control {
    --focus: var(--gold);
    position: absolute;
    top: 50%;
    display: grid;
    place-items: center;
    width: var(--tap);
    height: var(--tap);
    border: 1px solid var(--on-dark);
    border-radius: var(--r-pill);
    background: var(--ink);
    color: var(--on-dark);
    font-size: var(--step-1);
    line-height: 1;
    cursor: pointer;
    transform: translateY(-50%);
}
.gallery-control:hover { border-color: var(--murram); background: var(--murram); }
.gallery-prev { left: var(--space-12); }
.gallery-next { right: var(--space-12); }

.zoom-controls {
    --focus: var(--gold);
    position: absolute;
    right: var(--space-12);
    bottom: var(--space-12);
    display: flex;
    align-items: center;
    gap: var(--space-8);
    padding: var(--space-4) var(--space-8);
    border-radius: var(--r-sm);
    background: var(--ink);
    color: var(--on-dark);
    font-size: var(--step--2);
}
.zoom-controls button {
    display: grid;
    place-items: center;
    width: var(--tap);
    height: var(--tap);
    border: 1px solid var(--on-dark-muted);
    border-radius: var(--r-sm);
    background: transparent;
    cursor: pointer;
}
.zoom-controls button:hover { border-color: var(--murram); background: var(--murram); }
.zoom-controls button[disabled] { opacity: 0.5; cursor: not-allowed; }
.zoom-controls button[disabled]:hover { border-color: var(--on-dark-muted); background: transparent; }

.gallery-caption { min-height: 1.6em; margin: var(--space-12) 0 0; color: var(--text-muted); font-size: var(--step--1); }

.gallery-thumbs {
    display: flex;
    gap: var(--space-8);
    margin-top: var(--space-12);
    padding-bottom: var(--space-8);
    overflow-x: auto;
    scrollbar-width: thin;
}
.gallery-thumb {
    flex: 0 0 auto;
    width: 76px;
    height: var(--tap);
    padding: 0;
    overflow: hidden;
    border: 2px solid transparent;
    border-radius: var(--r-xs);
    background: var(--ash-deep);
    cursor: pointer;
}
.gallery-thumb img { width: 100%; height: 100%; object-fit: cover; }
.gallery-thumb[aria-pressed="true"] { border-color: var(--accent); }
.gallery-thumb:hover { border-color: var(--rule-strong); }

/* ==========================================================================
   FAQ
   ========================================================================== */

.faq-list { max-width: var(--measure-wide); border-top: 1px solid var(--rule); }
.faq-list details { border-bottom: 1px solid var(--rule); }
.faq-list summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-16);
    min-height: var(--tap);
    padding-block: var(--space-16);
    font-family: var(--font-display);
    font-size: var(--step-1);
    font-weight: 600;
    list-style: none;
    cursor: pointer;
}
.faq-list summary::-webkit-details-marker { display: none; }
.faq-list summary::after {
    flex: 0 0 auto;
    color: var(--accent);
    font-family: var(--font-text);
    font-size: var(--step-2);
    line-height: 1;
    content: "+";
}
.faq-list details[open] summary::after { content: "\2212"; }
.faq-list summary:hover { color: var(--accent); }
.faq-list details > p { max-width: var(--measure); margin: 0 0 var(--space-16); color: var(--text-muted); }

/* ==========================================================================
   Contact
   ========================================================================== */

.contact-layout { display: grid; gap: var(--space-48); align-items: start; }

.contact-details { margin: 0; }
.contact-details > div { padding-block: var(--space-16); border-top: 1px solid var(--rule); }
.contact-details dt { margin-bottom: var(--space-4); color: var(--text-muted); font-size: var(--step--1); font-weight: 600; }
.contact-details dd { margin: 0; }
.contact-details a { color: var(--accent); font-weight: 600; }
.contact-details a:hover { color: var(--accent-hover); }
.contact-link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-8);
    min-height: var(--tap);
}

/* The one raised surface on the site, so the shadow still means something. */
.form-card {
    padding: var(--space-32) var(--space-24);
    border: 1px solid var(--rule-strong);
    border-radius: var(--r-sm);
    background: var(--surface);
    box-shadow: var(--lift);
}

.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
    gap: var(--space-24);
    margin-block: var(--space-32);
}
.field { display: flex; flex-direction: column; }
.field-full { grid-column: 1 / -1; }
.field label { margin-bottom: var(--space-8); font-size: var(--step--1); font-weight: 600; }
.field .req { color: var(--danger); }

input, textarea, select {
    width: 100%;
    min-height: var(--tap);
    padding: var(--space-12);
    border: 1px solid var(--rule-strong);
    border-radius: var(--r-sm);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: var(--step-0);
    transition: border-color var(--ease);
}
textarea { min-height: 9rem; line-height: 1.5; resize: vertical; }
select { appearance: auto; }
input::placeholder, textarea::placeholder { color: var(--slate); }
input:focus-visible, textarea:focus-visible, select:focus-visible { border-color: var(--accent); }
input[aria-invalid="true"], textarea[aria-invalid="true"], select[aria-invalid="true"] { border-width: 2px; border-color: var(--danger); }

.field-error { margin-top: var(--space-8); color: var(--danger); font-size: var(--step--1); font-weight: 600; }

.form-summary {
    margin-bottom: var(--space-24);
    padding: var(--space-16);
    border: 2px solid var(--danger);
    border-radius: var(--r-sm);
    background: var(--danger-bg);
}
.form-summary h3 { margin-bottom: var(--space-8); color: var(--danger); font-size: var(--step-1); }
.form-summary ul { margin: 0; padding-left: var(--space-16); font-size: var(--step--1); }
.form-summary a { color: var(--danger); font-weight: 600; }

.messages { padding-top: var(--space-24); }
.messages p {
    max-width: none;
    margin: 0 0 var(--space-12);
    padding: var(--space-16);
    border-left: 4px solid var(--accent);
    border-radius: var(--r-sm);
    background: var(--surface);
    font-weight: 500;
}
.messages p:last-child { margin-bottom: 0; }
.messages .message-success { border-left-color: var(--ok); background: var(--ok-bg); }
.messages .message-error { border-left-color: var(--danger); background: var(--danger-bg); }

/* ==========================================================================
   CTA band and footer
   ========================================================================== */

.cta-band { padding-block: var(--section-y-tight); }
.cta-inner { display: grid; gap: var(--space-24); align-items: center; }
.cta-inner h2 { max-width: var(--measure-head); margin-bottom: var(--space-12); }
.cta-inner p { color: var(--on-dark-muted); }

/* The CTA band above is the same canopy green, so this boundary is a
   join, not a gap: the footer pays a block gap, not a section gap. */
.site-footer { padding-block: var(--space-32) var(--space-24); }
.footer-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
    gap: var(--space-32);
    align-items: start;
}
.footer-brand { grid-column: 1 / -1; }
.footer-logo { width: min(180px, 60%); height: auto; }
.footer-lede { max-width: var(--measure-note); margin-top: var(--space-16); color: var(--on-dark-muted); font-size: var(--step--1); }
.footer-grid h2 {
    margin-bottom: var(--space-8);
    color: var(--on-dark);
    font-family: var(--font-text);
    font-size: var(--step--1);
    font-weight: 700;
    letter-spacing: 0;
}
.footer-grid ul { margin: 0; padding: 0; list-style: none; }
.footer-grid li { font-size: var(--step--1); }
.address { margin: 0; font-size: var(--step--1); font-style: normal; }
.site-footer .address, .site-footer .address a { color: var(--on-dark-muted); }
.footer-grid a {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap);
    color: var(--on-dark-muted);
    text-decoration: none;
}
.footer-grid a:hover { color: var(--on-dark); text-decoration: underline; }

.social-row { display: flex; flex-wrap: wrap; gap: var(--space-8); margin-top: var(--space-16); padding: 0; list-style: none; }
/* Icon-only: the brand name stays in the accessible name, not on screen.
   Each mark carries its platform's own colour as the disc, with a white
   glyph on top — the one place in the site where a non-Syson colour is
   allowed, because these are other people's marks. */
.social-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: var(--tap);
    block-size: var(--tap);
    border: 1px solid var(--rule-dark);
    border-radius: var(--r-pill);
    background: var(--brand, transparent);
    color: var(--on-dark);
    text-decoration: none;
    transition: transform var(--ease);
}
.social-link--x { --brand: var(--brand-x); }
.social-link--instagram { --brand: var(--brand-instagram); }
.social-link--facebook { --brand: var(--brand-facebook); }
.social-link--tiktok { --brand: var(--brand-tiktok); }
.social-link--youtube { --brand: var(--brand-youtube); }
.social-link:hover { border-color: var(--gold); transform: translateY(-2px); }
/* Placeholder profiles: still focusable and readable, visibly not yet live.
   The brand colour stays, dimmed, so the row still reads as one set. */
.social-link--pending { border-style: dashed; opacity: 0.55; cursor: default; }
.social-link--pending:hover { border-color: var(--rule-dark); transform: none; }
.social-icon { flex: 0 0 auto; width: 20px; height: 20px; }

.footer-bottom {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-12);
    margin-top: var(--space-32);
    padding-top: var(--space-16);
    border-top: 1px solid var(--rule-dark);
    color: var(--on-dark-muted);
    font-size: var(--step--2);
}

.whatsapp-float {
    position: fixed;
    right: var(--space-16);
    bottom: var(--space-16);
    z-index: 30;
    display: inline-flex;
    align-items: center;
    gap: var(--space-8);
    min-height: var(--tap);
    padding-inline: var(--space-16);
    border-radius: var(--r-pill);
    background: var(--ink);
    color: var(--on-dark);
    font-size: var(--step--1);
    font-weight: 600;
    text-decoration: none;
    box-shadow: var(--lift);
    transition: background-color var(--ease);
}
.whatsapp-float:hover { background: var(--canopy); }
.whatsapp-float .social-icon { width: 22px; height: 22px; }
.whatsapp-float-label { white-space: nowrap; }

/* ==========================================================================
   Breakpoints — intrinsic sizing does most of the work; these only add
   columns and switch the navigation to its horizontal form.
   ========================================================================== */

@media (min-width: 40em) {
    .hero-copy { padding-block: var(--space-48); }
    .cta-inner { grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-32); }
    .cta-inner h2 { margin-bottom: var(--space-12); }
    .footer-brand { grid-column: auto; }
}

@media (min-width: 52em) {
    .ways { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: var(--space-48); align-items: start; }
    .split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-48); }
    .detail-layout { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
    /* The aside is usually shorter than the highlights/inclusions column
       beside it; pinning it keeps the CTA in view while that column
       scrolls, instead of leaving it stranded above a tall empty column. */
    .detail-aside { position: sticky; top: calc(76px + var(--space-16)); }
    .contact-layout { grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); }
    .form-card { padding: var(--space-48) var(--space-32); }
    .section-head { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-48); align-items: start; }
    .section-head h2 { margin-bottom: 0; }
    /* The argument gets the wider column; the list beside it is short lines. */
    .service-detail { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: var(--space-48); }
}

@media (min-width: 64em) {
    .hero-inner {
        grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
        align-items: stretch;
        /* Sized so real content is already on screen at 1440x900. min-height,
           not height, so a headline wrapping to a third line still grows the
           band. 100% (not 100vw) matches .shell and excludes the scrollbar;
           the photograph still bleeds right, only the copy is held to the
           shared left edge. */
        min-height: clamp(20rem, 60svh, 34rem);
        padding-left: var(--shell-inset);
    }
    .hero-copy {
        display: flex;
        flex-direction: column;
        justify-content: center;
        padding-block: var(--space-32);
        padding-inline: 0 var(--space-48);
    }
    .hero-figure img { aspect-ratio: auto; height: 100%; min-height: 0; }

    /* Desktop navigation: horizontal, always present, panel styling undone. */
    .nav-toggle { display: none; }
    .site-nav {
        position: static;
        max-height: none;
        padding: 0;
        overflow: visible;
        border-top: 0;
        background: transparent;
    }
    .site-nav[hidden] { display: block; }
    .site-nav ul { flex-direction: row; align-items: center; gap: var(--space-24); }
    .site-nav a { padding-block: var(--space-8); border-bottom: 0; font-size: var(--step--1); }
    .site-nav a[aria-current="page"] {
        color: var(--on-dark);
        text-decoration: underline;
        text-decoration-color: var(--gold);
        text-decoration-thickness: 3px;
        text-underline-offset: 0.4em;
    }
    .site-nav .nav-cta { margin-top: 0; }
    .nav-wrap { min-height: 76px; }
    body.nav-open { overflow: auto; }
}

/* Landscape phones: a sticky bar would eat too much of a short viewport.
   It stays relative, not static, because the nav panel is positioned
   against it. On the same short viewports the WhatsApp float shrinks to an
   icon-only circle (matching .social-link), because at this height its full
   pill sits over the hero copy rather than below the fold. */
@media (max-height: 30rem) {
    .site-header { position: relative; }
    .whatsapp-float {
        inline-size: var(--tap);
        block-size: var(--tap);
        padding-inline: 0;
        gap: 0;
        border-radius: var(--r-pill);
    }
    .whatsapp-float-label { display: none; }
}

/* ==========================================================================
   Motion and print
   ========================================================================== */

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

@media print {
    .site-header, .site-topbar, .whatsapp-float, .cta-band, .nav-toggle, .ridge, .ridge-rule { display: none; }
    /* --ink is the darkest value in whichever palette is active, so this
       prints dark type on paper in the dark theme as well as the light one.
       Without it a dark-theme page prints its near-white --text on white. */
    body { background: none; color: var(--ink); }
    .band-dark { background: none; color: var(--ink); }
    .card, .form-card, .detail-aside, .messages p, input, textarea, select { background: none; }
}
