@charset "utf-8";

/* ==========================================================================
   Geneseo Super Wash: site stylesheet
   CSS Grid only. No flexbox anywhere in this file. The single exception is
   .media-split--wrap, which floats a figure so body copy can wrap around it
   and then continue below it: grid cannot express that. See section 8c.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens
   Brand hex values sampled directly from images/GeneseoSuper3.png and
   images/dogKid.png rather than from a screenshot.
   -------------------------------------------------------------------------- */
:root {
    /* Brand */
    --blue-deep:    #13509F;  /* hero panel, Services band, footer */
    --blue-heading: #13509F;  /* section headings, page titles */
    --blue-card:    #C3DAF8;  /* light blue content cards */
    --blue-text:    #13509F;  /* text inside light blue cards (5.49:1 on --blue-card) */
    --blue-text-dk: #0E3D7A;  /* denser card ink for reference tables (7.48:1) */
    --green-cta:    #A0CF67;  /* Explore buttons */
    --green-cta-dk: #8AB854;  /* button hover */
    --gray-nav:     #D5D4D4;  /* top nav bar */
    --ink:          #222222;  /* body copy on white */
    --white:        #FFFFFF;

    /* Type scale: fluid, no media queries needed */
    --step-h1:   clamp(1.75rem, 1.1rem + 2.6vw, 2.75rem);
    --step-h2:   clamp(1.4rem, 1rem + 1.6vw, 2rem);
    --step-h3:   clamp(1.15rem, 0.95rem + 0.9vw, 1.5rem);
    --step-body: clamp(1rem, 0.95rem + 0.25vw, 1.125rem);

    /* Spacing */
    --space-xs: 0.5rem;
    --space-sm: 1rem;
    --space-md: clamp(1.5rem, 3vw, 2.5rem);
    --space-lg: clamp(2.5rem, 6vw, 5rem);

    /* Shape */
    --radius: 14px;
    --container: 1200px;

    /* Type families */
    --font-heading: 'Poppins', 'Segoe UI', system-ui, sans-serif;
    --font-body: system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;
}

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

body {
    margin: 0;
    font-family: var(--font-body);
    font-size: var(--step-body);
    line-height: 1.6;
    color: var(--ink);
    background: var(--white);
    overflow-x: hidden;

    /* Sticky footer. On short pages (Storage Units, Hours) the footer used to
       stop wherever the content ran out and leave white space under it. The
       three rows are header / main / footer; main takes 1fr so it absorbs the
       slack and pushes the footer to the bottom of the viewport, while longer
       pages are unaffected because 1fr never shrinks content below its size.
       .skip-link is position:absolute and <script> is display:none, so neither
       becomes a grid item and the row count stays at three.
       dvh second so mobile browsers measure against the visible viewport
       rather than the taller one behind the address bar. */
    min-height: 100vh;
    min-height: 100dvh;
    display: grid;
    grid-template-rows: auto 1fr auto;
}

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

h1, h2, h3, h4 {
    font-family: var(--font-heading);
    font-weight: 700;
    line-height: 1.2;
    margin: 0 0 var(--space-sm);
    color: var(--blue-heading);
}

h1 { font-size: var(--step-h1); }   /* 2.75rem  page title           */
h2 { font-size: var(--step-h2); }   /* 2rem     section heading      */
h3 { font-size: var(--step-h3); }   /* 1.5rem   subsection / bay name */
/* h4 had no size rule and fell through to body size, so card titles were
   marked up as h3 to look right, which made them identical to the bay
   headings above them. Giving h4 its own step lets the cards drop a level
   and restores the scale: 2.75 / 2 / 1.5 / 1.125rem. */
h4 { font-size: 1.125rem; }

p { margin: 0 0 var(--space-sm); }
p:last-child { margin-bottom: 0; }

a { color: var(--blue-deep); }

:focus-visible {
    outline: 3px solid var(--blue-deep);
    outline-offset: 3px;
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    background: var(--white);
    color: var(--blue-deep);
    padding: var(--space-xs) var(--space-sm);
    z-index: 100;
}
.skip-link:focus {
    left: var(--space-sm);
    top: var(--space-xs);
}

/* --------------------------------------------------------------------------
   3. Layout utilities (Grid only)
   -------------------------------------------------------------------------- */
.container {
    max-width: var(--container);
    margin-inline: auto;
    padding-inline: 1.5rem;
}
.container--narrow { --container: 1000px; }

.center { display: grid; place-items: center; }
.text-center { text-align: center; }

/* ---------------------------------------------------------------------------
   GLOBAL. .container and .section below set the horizontal track and the
   vertical rhythm for EVERY page on the site. There are no per-page overrides
   by design: that is what keeps the nav, the body copy and the card grids on
   one shared set of edges. The trade is blast radius. Changing either rule
   reflows all seven pages, so check them all, not just the one you are on.

   Add space by adding a section, never by adding a margin to something inside
   one. Page-specific spacing patches are what this refactor removed.
   --------------------------------------------------------------------------- */

/* Floor 2.5rem so phones do not carry desktop-sized dead space between
   sections; ceiling 4rem so wide screens do not drift back to the 10rem
   section-to-section gaps this replaced. */
.section { padding-block: clamp(2.5rem, 5vw, 4rem); }
/* Matches .section's rhythm so the two never disagree. */
.section-block { margin-top: clamp(2.5rem, 5vw, 4rem); }

/* A heading and the line under it are ONE unit. The block rhythm applies
   between .section-block siblings, never between a heading and its subtitle:
   that gap is 0.5rem and nothing else may set it. */
.section-header {
    text-align: center;
    margin-bottom: var(--space-md);
}
.section-header > * { margin-block: 0; }
.section-header > * + * { margin-top: 0.5rem; }
.section-header p {
    max-width: 60ch;
    margin-inline: auto;
    color: var(--ink);
}
.section--blue {
    background: var(--blue-deep);
    color: var(--white);
}
.section--blue h1,
.section--blue h2,
.section--blue h3 { color: var(--white); }

/* Grid gap owns the rhythm here, so zero the children's own block margins
   to stop the two from stacking up. */
.stack > * { margin-block: 0; }
.stack > * + * { margin-top: var(--space-sm); }

.prose { max-width: 70ch; }
.prose--center { margin-inline: auto; }

.rule {
    border: 0;
    border-top: 1px solid #D8D8D8;
    margin-block: var(--space-md) 0;
}
/* Sits flush under the hero so the mascot appears to stand on it. */
.rule--hero { margin-top: 0; }

/* Responsive card row: auto-collapses, equal heights free */
.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: var(--space-md);
    align-items: stretch;
}
.card-grid--two { grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); }

/* Keeps the base 280px min, which fits three cards in one even row inside
   .container--narrow. --two's 320px min wrapped the third onto its own line.
   Scoped modifier rather than a change to .card-grid's gap, which is shared
   with the home and hours grids. */
.card-grid--tight { gap: 1.5rem; }

/* Two-column asymmetric (mascot + reviews) */
.split {
    display: grid;
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.6fr);
    gap: var(--space-md);
    align-items: center;
}

/* --------------------------------------------------------------------------
   4. Header / navigation
   -------------------------------------------------------------------------- */
.site-header {
    background: var(--gray-nav);
    border-radius: 5px;
    /* Matches .container's content box exactly (its max-width less its two
       1.5rem gutters), so the bar's edges line up with the body copy at every
       width. Trailing margin is 0: the first section's padding owns that gap. */
    margin: var(--space-xs) auto 0;
    width: min(var(--container) - 3rem, 100% - 3rem);
}

.nav-toggle {
    display: none;
    width: 100%;
    min-height: 44px;
    padding: var(--space-xs) var(--space-sm);
    background: none;
    border: 0;
    font: inherit;
    font-family: var(--font-heading);
    font-weight: 600;
    color: var(--blue-deep);
    cursor: pointer;
}
.nav-toggle__bars {
    display: inline-block;
    width: 22px;
    height: 2px;
    margin-right: var(--space-xs);
    vertical-align: middle;
    background: currentColor;
    box-shadow: 0 -7px 0 currentColor, 0 7px 0 currentColor;
}

.nav-list {
    display: grid;
    grid-auto-flow: column;
    justify-content: center;
    gap: clamp(1rem, 3vw, 2.75rem);
    list-style: none;
    margin: 0;
    padding: var(--space-xs);
}
.nav-list a {
    display: grid;
    place-items: center;
    min-height: 44px;
    padding: 0 var(--space-xs);
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--blue-deep);
    text-decoration: none;
    text-align: center;
}
.nav-list a:hover { text-decoration: underline; }
.nav-list a[aria-current="page"] {
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 4px;
}

/* --------------------------------------------------------------------------
   5. Hero banner
   -------------------------------------------------------------------------- */

/* The mascot's shoes land exactly on .rule--hero: he hangs --hero-mascot-drop
   below the panel's bottom edge, and the hero reserves that same amount of
   padding underneath. His negative margin has to clear the panel's own padding
   first, hence the sum in .hero__mascot-cell. */
.hero {
    --hero-panel-pad: var(--space-md);
    --hero-mascot-drop: 2.5rem;
    /* The nav bar carries no bottom margin (the section rhythm owns that gap
       everywhere else), but the home page opens on .hero rather than a
       .section, so it has to supply its own breathing room under the bar. */
    padding-top: var(--space-md);
    padding-bottom: var(--hero-mascot-drop);
}

.hero__panel {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: var(--space-sm);
    max-width: 742px;
    margin-inline: auto;
    padding: var(--hero-panel-pad);
    background: var(--blue-deep);
    border-radius: var(--radius);
}

.hero__brand { display: grid; justify-items: center; gap: var(--space-sm); }
.hero__logo { max-width: 280px; }

.hero__badge {
    margin: 0;
    padding: var(--space-xs) var(--space-md);
    background: var(--white);
    color: var(--blue-deep);
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: var(--step-h3);
    border-radius: 5px;
}

.hero__mascot-cell {
    align-self: end;
    margin-bottom: calc((var(--hero-panel-pad) + var(--hero-mascot-drop)) * -1);
}
.hero__mascot { width: clamp(110px, 18vw, 190px); }

/* --------------------------------------------------------------------------
   6. Page title block
   -------------------------------------------------------------------------- */
.page-title {
    text-align: center;
    margin-bottom: var(--space-md);
}
/* When the title block is the whole section, the section padding already
   supplies the gap below it and this margin would double it up. */
.page-title:last-child { margin-bottom: 0; }
.page-title h1 { color: var(--blue-heading); }
.page-title p {
    max-width: 70ch;
    margin-inline: auto;
    color: var(--ink);
}

/* One rhythm for the whole block: zero the children's own margins so the
   sibling rule owns the spacing and the two never stack up. */
.page-title > * { margin-block: 0; }
.page-title > * + * { margin-top: var(--space-sm); }

/* Standfirst line between the h1 and the body copy: brand blue and a step up
   in size, so a title block holding both a tagline and a paragraph reads as a
   hierarchy instead of two identical blocks of text. */
.page-title .page-title__lead {
    max-width: 60ch;
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: var(--step-h3);
    line-height: 1.35;
    color: var(--blue-heading);
}

/* --------------------------------------------------------------------------
   7. Buttons
   -------------------------------------------------------------------------- */
.btn {
    display: inline-grid;
    place-items: center;
    padding: 0.75rem 1.75rem;
    border: 0;
    border-radius: 8px;
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 1rem;
    text-align: center;
    text-decoration: none;
    min-height: 44px;
    cursor: pointer;
    transition: background-color .15s ease, transform .15s ease;
}
.btn--primary {
    background: var(--green-cta);
    color: var(--white);
}
.btn--primary:hover {
    background: var(--green-cta-dk);
    transform: translateY(-1px);
}
.btn:focus-visible {
    outline: 3px solid var(--blue-deep);
    outline-offset: 3px;
}

/* Two or more buttons side by side, centred; wraps to a stack when there is
   no room rather than squashing the labels. */
.btn-row {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: max-content;
    justify-content: center;
    align-items: stretch;
    gap: var(--space-sm);
    margin-top: var(--space-md);
}
@media only screen and (max-width: 620px) {
    .btn-row {
        grid-auto-flow: row;
        justify-items: center;
    }
}

/* --------------------------------------------------------------------------
   8. Cards
   -------------------------------------------------------------------------- */
.card {
    display: grid;
    grid-template-rows: auto 1fr auto;
    background: var(--blue-card);
    color: var(--blue-text);
    border-radius: var(--radius);
    overflow: hidden;
}
.card__media { grid-row: 1; margin: 0; }
.card__media img {
    width: 100%;
    aspect-ratio: 16 / 10;
    object-fit: cover;
}

/* Map embed sits in the media row so it matches a card image. The radius is
   repeated here rather than left to the card's overflow:hidden, because iframe
   clipping by an ancestor's rounded corners is unreliable. */
.card__map {
    grid-row: 1;
    margin: 0;
    overflow: hidden;
    border-radius: var(--radius) var(--radius) 0 0;
}
.card__map iframe {
    display: block;
    width: 100%;
    height: clamp(200px, 20vw, 260px);
    border: 0;
}
.card__body {
    grid-row: 2;
    display: grid;
    align-content: start;
    gap: var(--space-sm);
    padding: var(--space-md);
}
/* gap handles the spacing; drop the children's own margins so it isn't doubled */
.card__body > * { margin-block: 0; }
.card__foot {
    grid-row: 3;
    display: grid;
    place-items: center;
    padding: 0 var(--space-md) var(--space-md);
}
.card h2,
.card h3,
.card h4 { color: var(--blue-text); margin: 0; }

/* Review cards */
.card blockquote {
    margin: 0;
    font-style: italic;
}
.card cite {
    display: block;
    margin-top: var(--space-xs);
    font-style: normal;
    font-weight: 700;
    text-align: center;
}

/* Callout card (Community) */
.callout {
    background: var(--blue-card);
    color: var(--blue-text);
    border-radius: var(--radius);
    padding: var(--space-md);
    text-align: center;
    max-width: 70ch;
    margin: var(--space-md) auto;
}
.callout a { color: var(--blue-text); font-weight: 700; }

/* Definition list of hours */
.hours-list {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-xs) var(--space-sm);
    margin: 0;
}
.hours-list dt { font-weight: 700; }
.hours-list dd { margin: 0; }

/* Column label for the price table. Left-aligned so it sits in the same column
   as the row titles below it (10X10, Move-In Special, ...) and reads as one of
   them rather than as a stray line floating over the figures. */
.price-list__caption {
    max-width: 40rem;
    margin: var(--space-md) auto 0;
    font-family: var(--font-heading);
    font-weight: 700;
    color: var(--blue-heading);
}
.price-list__caption + .price-list { margin-top: 0.25rem; }

/* Price table (Storage Units): label left, figure right, ruled rows.
   40rem rather than 34rem: the offer rows carry a sentence in the right-hand
   column, which needs more room than a $49/mo figure did. */
.price-list {
    display: grid;
    grid-template-columns: 1fr auto;
    max-width: 40rem;
    margin: var(--space-md) auto 0;
    font-family: var(--font-heading);
}
.price-list dt,
.price-list dd {
    padding-block: 0.75rem;
    border-top: 1px solid rgba(19, 80, 159, 0.25);
}
.price-list dt {
    font-weight: 600;
    padding-right: var(--space-sm);
}
.price-list dd {
    margin: 0;
    text-align: right;
    font-weight: 800;
    color: var(--blue-heading);
}
/* The offer rows hold a sentence, not a figure: same colour so they still read
   as the row's value, but stepped down from 800 so a full line of Poppins at
   that weight does not shout over the prices above it. */
.price-list__offer { font-weight: 600; }
/* Each half of an offer sentence is one unbreakable piece, so when the column
   runs out of room the line breaks between the two halves ("Pay for 3 months" /
   "receive 1 month FREE") instead of wherever the last word happened to fit. */
.price-list__offer span { display: inline-block; }

.price-list__contact {
    margin-top: var(--space-md);
    text-align: center;
    font-weight: 700;
}

.price-list dt:last-of-type,
.price-list dd:last-of-type { border-bottom: 1px solid rgba(19, 80, 159, 0.25); }

/* Simple bulleted list inside cards (Locations) */
.feature-list {
    margin: 0;
    padding-left: 1.25rem;
}
.feature-list li + li { margin-top: 0.25rem; }

/* Numbered how-it-works lists (Storage Units, Car Wash) */
.steps-list {
    margin-block: var(--space-sm) 0;
    padding-left: 1.5rem;
    text-align: left;
}
.steps-list li + li { margin-top: var(--space-xs); }

/* Pill grid: unit sizes (Storage Units) and organisation list (Community) */
/* The pill grid reads as one dense block of colour, so the heading above it
   needs more air than the 1rem the base h2 rule gives, or the two look welded
   together. Collapses with the heading's own margin, so this value wins. */
.org-grid,
.pill-grid {
    display: grid;
    gap: 1rem;
    list-style: none;
    margin: var(--space-md) 0 0;
    padding: 0;
}
.pill-grid { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }

/* Fixed 3 across: the 15 organisations divide into 5 clean rows. auto-fit
   resolved to 4 across at 1200px and left an orphan hole on the last row. */
.org-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.org-grid li,
.pill-grid li {
    background: var(--blue-card);
    color: var(--blue-text);
    border-radius: 8px;
    padding: .75rem 1rem;
}

/* Equal height whether the name runs to one line or three. Grid, not flex:
   see the file header. */
.org-grid li {
    display: grid;
    align-items: center;
    min-height: 80px;
    padding: 1.25rem;
}
.pill-grid--sizes li {
    text-align: center;
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: var(--step-h3);
}

/* Phone links in card context */
.tel-link {
    color: var(--blue-text);
    font-weight: 700;
    text-decoration: none;
}
.tel-link:hover { text-decoration: underline; }

/* --------------------------------------------------------------------------
   8b. Home page
   -------------------------------------------------------------------------- */

/* Section heading with the mascot in its own grid cell, so it can never
   overlap the heading text (the old build used absolute positioning). */
/* The band's own top padding plus the mascot's height left a large gap above
   "Our Services", so the section opens tighter and the mascot bleeds into that
   padding instead of pushing the heading down. */
/* Enough headroom for the enlarged mascot to sit in the corner without its cap
   crossing the band's top edge. */
.section--services { padding-top: var(--space-md); }

.services-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, auto) minmax(0, 1fr);
    align-items: center;
    gap: var(--space-sm);
    margin-bottom: var(--space-md);
}
/* Roughly double the default h2, and centred in the band: the empty 1fr track
   on the left mirrors the mascot's track on the right, so the middle column is
   the true centre of the container. */
.services-head h2 {
    grid-column: 2;
    margin: 0;
    text-align: center;
    font-size: clamp(2rem, 1.3rem + 2.9vw, 3.75rem);
}
.services-head__mascot {
    grid-column: 3;
    justify-self: end;
    width: clamp(120px, 17vw, 230px);
    /* Decorative: let it overflow the row rather than set the row's height. */
    margin-block: -1.25rem;
}

/* --- Services cards -------------------------------------------------------
   Centred, denser, and on the site's Poppins stack. Body copy was inheriting
   --font-body (system-ui) because --font-heading is only applied to headings;
   these rules opt the card text into the friendlier face. Scoped to this
   section so the Locations, Hours and About cards keep their left-aligned
   reading layout. */
.section--services .card__body {
    gap: var(--space-xs);
    padding: var(--space-sm) var(--space-md);
    text-align: center;
    font-family: var(--font-heading);
    font-weight: 500;
}
.section--services .card h3 {
    font-size: clamp(1.35rem, 1.05rem + 1.1vw, 1.75rem);
    font-weight: 800;
}
/* Each column is three detached blocks stacked on the blue band, so the
   background shows through between them. The middle row is 1fr, which is what
   makes the two text cards come out equal height without a fixed height. */
.service {
    display: grid;
    grid-template-rows: auto 1fr auto;
}

/* Rounded on all four corners now that it is no longer fused to the card. */
.service__photo {
    margin: 0;
    border-radius: var(--radius);
    overflow: hidden;
}
.service__photo img {
    width: 100%;
    aspect-ratio: 16 / 10;
    object-fit: cover;
}

/* Percentage margins resolve against the column's inline size, so both gaps
   stay locked to the column width as the grid reflows. */
.service__card { margin-top: 9%; }

.service__cta {
    margin-top: 8%;
    display: grid;
    justify-items: center;
}
/* Sits on the blue, not in the card. Width is a share of the column so the
   long label wraps to two centred lines on its own. */
.service__cta .btn {
    width: 55%;
    border-radius: 8px;
    padding-inline: var(--space-sm);
    font-weight: 800;
    line-height: 1.25;
    text-align: center;
}

/* The whole line is the tap target, underlined so it reads as one link. */
.contact-link {
    font-family: var(--font-heading);
    font-weight: 700;
    color: var(--blue-text);
    text-decoration: underline;
    text-underline-offset: 3px;
}
.contact-link:hover { text-decoration-thickness: 2px; }

.split__mascot { margin-inline: auto; }

.reviews-title { margin-bottom: var(--space-md); }

/* Beats `.stack > * + *` on source order, so the button keeps its wider gap. */
.reviews-cta { margin-top: var(--space-md); }

/* --------------------------------------------------------------------------
   8b-2. Hours page
   The default card ink at body size read faintly against the light blue, so
   this page uses the denser blue, larger type and ruled rows.
   -------------------------------------------------------------------------- */
.card--hours { color: var(--blue-text-dk); }
.card--hours h2,
.card--hours h3 { color: var(--blue-text-dk); }
.card--hours .tel-link { color: var(--blue-text-dk); }

.card--hours .hours-list {
    font-size: 1.0625rem;
    gap: 0;
}
.card--hours .hours-list dt,
.card--hours .hours-list dd {
    padding-block: 0.5rem;
    border-top: 1px solid rgba(14, 61, 122, 0.28);
}
.card--hours .hours-list dt { padding-right: var(--space-sm); }
.card--hours .hours-list dd {
    text-align: right;
    font-weight: 600;
}

/* The always-open line is the answer most visitors came for. */
.hours-banner {
    display: grid;
    place-items: center;
    padding: 0.6rem var(--space-sm);
    border-radius: 8px;
    background: var(--blue-deep);
    color: var(--white);
    font-family: var(--font-heading);
    font-weight: 700;
    text-align: center;
}

.hours-note {
    font-weight: 600;
    color: var(--blue-text-dk);
}

/* --------------------------------------------------------------------------
   8c. About page
   -------------------------------------------------------------------------- */
/* Copy on the left, image on the right. Stacks text-first on narrow screens. */
.media-split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 3rem;
    align-items: center;
}
.media-split__text > :first-child { margin-top: 0; }

/* Magazine wrap (Community intro): the copy runs alongside the photo and then
   continues underneath it once it passes the image's bottom edge.
   This is the ONLY float on the site, and it is deliberate: a grid column
   cannot reflow its own text under a sibling cell, so grid genuinely cannot
   express this layout. Everything else on the site stays grid.
   The measure is capped so the lines that fall below the image do not run the
   full 1152px of the container, which would be ~135 characters and unreadable. */
.media-split--wrap {
    display: block;
    max-width: 90ch;
    margin-inline: auto;
}
/* Contains the float so the section's own padding still measures correctly
   when the copy is shorter than the photo. */
.media-split--wrap::after {
    content: "";
    display: block;
    clear: both;
}
.media-split--wrap .media-split__figure {
    float: right;
    width: min(45%, 460px);
    /* Small top offset so the image's cap aligns with the first line's x-height
       rather than its ascender. */
    margin: 0.35rem 0 var(--space-sm) var(--space-md);
}

.media-split__figure { margin: 0; }
.media-split__figure img {
    width: 100%;
    border-radius: var(--radius);
    object-fit: cover;
}

/* --------------------------------------------------------------------------
   8d. Community page
   -------------------------------------------------------------------------- */
/* Secondary hero banner (every page but home). The PNG is a pre-rendered panel
   with the mascot breaking past its lower edge, so it needs no background,
   radius or padding of its own: just the same top offset .hero uses, and a
   full-width image so its edges land on the nav bar's edges. */
.page-hero { padding-top: var(--space-md); }
.page-hero__img { width: 100%; }

/* Photo pair (About). Equal columns, equal heights: the two source images have
   different aspect ratios, so a fixed ratio plus object-fit crops them to match
   rather than letting one column set a taller row. */
.photo-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 1.5rem;
    /* Sits directly above the line it illustrates, so it needs its own gap
       below: the paragraph that follows carries no top margin. */
    margin-bottom: var(--space-md);
}
.photo-grid__item { margin: 0; }
.photo-grid__item img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: var(--radius);
}

.page-figure {
    margin: var(--space-md) auto;
    max-width: 700px;
}
.page-figure img {
    width: 100%;
    border-radius: var(--radius);
}

/* --------------------------------------------------------------------------
   9. Footer
   -------------------------------------------------------------------------- */
/* No margin-top: the last section's padding already supplies the gap. The old
   --space-lg here stacked on top of it and made the footer seam the widest
   piece of whitespace on every page. */
.site-footer {
    background: var(--blue-deep);
    color: var(--white);
    padding-block: var(--space-md);
}
.site-footer a { color: var(--white); }

/* Full-bleed with only a small gutter, so the logo sits hard against the left
   edge of the footer and the nav row has room to stay on one line. */
.footer-inner {
    width: 100%;
    padding-inline: clamp(0.75rem, 1.5vw, 1.5rem);
}

.footer-grid {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    gap: var(--space-sm) var(--space-md);
    align-items: center;
}

.footer-brand {
    display: grid;
    grid-auto-flow: column;
    align-items: center;
    justify-self: start;
    gap: var(--space-sm);
}
.footer-brand__logo { width: 150px; }
.footer-brand__social { width: 40px; }

.footer-contact { min-width: 0; }
.footer-address { margin-bottom: 0; }

/* Its own row under the grid, centred on the footer and last in the stack. */
.footer-credit {
    margin: var(--space-md) 0 0;
    font-size: 0.875rem;
    text-align: center;
}

/* Single row: one link per column. */
.footer-nav ul {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: max-content;
    justify-content: end;
    gap: var(--space-xs) clamp(0.75rem, 1.6vw, 1.75rem);
    list-style: none;
    margin: 0;
    padding: 0;
}
.footer-nav a {
    font-size: 0.95rem;
    text-decoration: none;
    white-space: nowrap;
}
.footer-nav a:hover { text-decoration: underline; }

/* --------------------------------------------------------------------------
   10. Responsive
   -------------------------------------------------------------------------- */
@media only screen and (max-width: 1024px) {
    .split { grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); }
}

@media only screen and (max-width: 860px) {
    .split { grid-template-columns: minmax(0, 1fr); }
    .split__mascot { max-width: 220px; margin-inline: auto; }

    .media-split { grid-template-columns: minmax(0, 1fr); }
    .media-split__figure { max-width: 700px; margin-inline: auto; }
}

@media only screen and (max-width: 900px) {
    .org-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media only screen and (max-width: 600px) {
    .org-grid { grid-template-columns: minmax(0, 1fr); }

    /* Phone widths: hold the offer sentences to their deliberate two-line
       shape instead of letting the break land wherever the text runs out. Both
       halves stay right-aligned, so they stack under the prices as one block. */
    .price-list__offer span { display: block; }

    /* Too little room left beside a float to set a readable line, so the photo
       goes back to a full-width block above the copy. */
    .media-split--wrap .media-split__figure {
        float: none;
        width: auto;
        margin: 0 0 var(--space-sm);
    }
}

/* Not enough room for brand + address + the full link row side by side, so the
   links drop to their own row and stay on one line for as long as they fit. */
@media only screen and (max-width: 1100px) {
    .footer-grid { grid-template-columns: auto minmax(0, 1fr); }
    .footer-nav {
        grid-column: 1 / -1;
        justify-self: center;
    }
    .footer-nav ul { justify-content: center; }
}

@media only screen and (max-width: 768px) {
    .footer-grid {
        grid-template-columns: minmax(0, 1fr);
        justify-items: center;
        text-align: center;
    }
    .footer-brand { justify-self: center; }
    .footer-nav { grid-column: auto; }
}

/* Below this the six links can no longer share a line: let them wrap. */
@media only screen and (max-width: 640px) {
    .footer-nav ul {
        grid-auto-flow: row;
        grid-template-columns: repeat(2, minmax(0, auto));
    }
}

@media only screen and (max-width: 720px) {
    .nav-toggle { display: block; }

    .nav-list { display: none; }
    .nav-list.is-open {
        display: grid;
        grid-auto-flow: row;
        justify-items: center;
        gap: 0;
        padding-bottom: var(--space-xs);
    }
    .nav-list.is-open a { width: 100%; }

    .hero {
        --hero-mascot-drop: 2.5rem;
    }
    .hero__panel {
        grid-template-columns: minmax(0, 1fr);
        justify-items: center;
    }
    .hero__mascot { width: 140px; }

    .card-grid,
    .card-grid--two { grid-template-columns: minmax(0, 1fr); }

    /* Decorative only: at this width it crowds the heading and pushes it
       off centre, so drop it rather than shrink it further. */
    .services-head { grid-template-columns: minmax(0, 1fr); }
    .services-head h2 { grid-column: 1; }
    .services-head__mascot { display: none; }
}

@media only screen and (max-width: 480px) {
    .footer-nav ul { grid-template-columns: minmax(0, auto); }
    .footer-brand__logo { width: 120px; }
    .hero__logo { max-width: 220px; }
}

@media (prefers-reduced-motion: reduce) {
    .btn { transition: none; }
    .btn--primary:hover { transform: none; }
}
