/* Public Sans, self-hosted — no third-party request, so no visitor of this site is disclosed to a
   CDN. A variable font covering 400-800, which is why one file serves every weight in the scale.
   unicode-range means English pages fetch only the latin file (26 KB); the others load only if a
   page actually contains those characters.
   font-display: swap renders in the fallback immediately rather than holding text invisible.
   Files and provenance: wwwroot/brand/fonts/README.md */

@font-face {
    font-family: "Public Sans";
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url("/brand/fonts/public-sans-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Public Sans";
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url("/brand/fonts/public-sans-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "Public Sans";
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url("/brand/fonts/public-sans-vietnamese.woff2") format("woff2");
    unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}

@font-face {
    font-family: "Public Sans";
    font-style: italic;
    font-weight: 400 800;
    font-display: swap;
    src: url("/brand/fonts/public-sans-latin-italic.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Public Sans";
    font-style: italic;
    font-weight: 400 800;
    font-display: swap;
    src: url("/brand/fonts/public-sans-latin-ext-italic.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "Public Sans";
    font-style: italic;
    font-weight: 400 800;
    font-display: swap;
    src: url("/brand/fonts/public-sans-vietnamese-italic.woff2") format("woff2");
    unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}

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

/*
  Brand palette, taken from the blueberry-carton logo: the pulp carton is #497c80 and the berries
  are #3963ab. Those two are fixed — everything else here is derived from them by mixing toward
  black or white, so the whole site stays in the logo's family rather than drifting into
  approximations of it.

  Every foreground/background pairing used below clears WCAG AA for body text (4.5:1). The tightest
  is white on --color-carton at 4.69:1, so do not lighten the carton color without re-checking it.
*/
:root {
    /* Carton — the teal. Primary surfaces: header, hero, mobile nav. */
    --color-carton: #497c80;
    --color-carton-dark: #2a484a;
    --color-carton-darker: #1c2f31;
    --color-carton-light: #dee7e8;
    /* The one carton step dark enough to draw a structural line on paper: 3.00:1, exactly the
       WCAG 1.4.11 floor for a non-text element you have to see in order to read the thing.
       carton-light is 1.16:1 against paper and disappears -- it is a fill, not a line. */
    --color-carton-mid: #6e9698;

    /* Berry — the blue. Links, buttons, accents on light ground. */
    --color-berry: #3963ab;
    --color-berry-dark: #284578;
    --color-berry-light: #e1e8f2;

    /* Ink and paper. The logo is heavy black linework on paper stock, so the text color is a
       near-black carrying the carton's cool cast, and the page ground is a warm off-white. */
    --color-ink: #12201f;
    --color-paper: #f8f6f1;
    --color-muted: #33575a;

    /* Semantic aliases — use these in components so the brand mapping can change in one place. */
    --color-primary: var(--color-carton);
    --color-accent: var(--color-berry);
    --color-text: var(--color-ink);
    --color-bg: var(--color-paper);

    /* Public Sans — drawn for the US Web Design System, so built for civic text at small
       sizes. Self-host it; do not load from a third-party CDN. Falls back to the system
       sans until the webfont is installed. */
    --font-body: "Public Sans", system-ui, sans-serif;

    /* Paper texture, cut from the same stock the logo was drawn on. It is a grayscale tile applied
       with background-blend-mode: multiply, so this single asset tints whatever color sits under
       it — paper, carton and the footer all share it instead of needing three variants.
       See wwwroot/brand/README.md for how it was derived. */
    --paper-texture: url("/brand/paper-texture.png");
}

/* Every textured surface sets its own background-color and then multiplies the tile over it. */
body,
.site-header,
.hero,
.site-footer {
    background-image: var(--paper-texture);
    background-repeat: repeat;
    background-blend-mode: multiply;
}

/* Column layout so the footer is pushed to the bottom of the viewport on pages too short to fill
   it — otherwise it rides up under the content, which it was doing everywhere and was most obvious
   on the calendar pages. main takes the slack; header and footer keep their natural height. */
body {
    font-family: var(--font-body);
    color: var(--color-text);
    background-color: var(--color-bg);
    line-height: 1.6;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

main { flex: 1 0 auto; }

.site-header,
.site-footer { flex-shrink: 0; }

a { color: var(--color-berry); }
a:hover { color: var(--color-berry-dark); }

/* The palette changes link and button colors, so an explicit focus ring is needed — otherwise
   keyboard users lose the browser default without anything replacing it. */
:focus-visible {
    outline: 3px solid var(--color-berry);
    outline-offset: 2px;
    border-radius: 2px;
}

.container {
    max-width: 1100px;
    margin: 0 auto;
    padding: 0 1.25rem;
}

/* Logo lockups — a mark centered in the void of the arched wordmark.
   The void was measured off the artwork rather than eyeballed: its centre is 51.6% / 52.6% and the
   largest circle that fits without touching the letterforms is 54.7% of the wordmark's width.
   The two variants below are the approved placements; they are not interchangeable, because the
   carton is 420x296 (wider than tall) and so reads much larger than the near-square berry at the
   same width percentage. */
.lockup {
    position: relative;
    display: block;
    width: 100%;
    margin-inline: auto;
}

.lockup-word {
    display: block;
    width: 100%;
    height: auto;
}

.lockup-mark {
    position: absolute;
    left: var(--lockup-x);
    top: var(--lockup-y);
    width: var(--lockup-size);
    height: auto;
    transform: translate(-50%, -50%);
}

.lockup--berry  { --lockup-size: 37%; --lockup-x: 51.4%; --lockup-y: 51.8%; }
.lockup--carton { --lockup-size: 62%; --lockup-x: 49.4%; --lockup-y: 53.2%; }

/* Home page masthead. Paper ground on purpose — see the Grounds table in the brand book: the full
   colour lockup is approved on paper, deep teal (reversed) and white, but not on carton teal, which
   is what the hero is.
   Width is capped at 70% rather than 100% so the required clear space — 15% of the lockup's width on
   every side — holds at any viewport, and 70% of the narrowest phone still clears the 160px minimum
   below which the brush strokes close up. */
.masthead {
    padding: 4rem 1.25rem 3rem;
    text-align: center;
}

.masthead .lockup {
    width: min(70%, 30rem);
}

/* Header */
.site-header {
    background-color: var(--color-carton);
    color: #fff;
    padding: 1rem 0;
}

.site-header .container {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.site-logo {
    color: #fff;
    font-size: 1.25rem;
    font-weight: 700;
    text-decoration: none;
}

/* A picked logo replaces the site name outright, so it has to sit on the same baseline the text
   did. Capped by height rather than width: editors will not all upload the same aspect ratio, and
   the header band is a fixed 1rem of padding either side of this. */
.site-logo img {
    display: block;
    height: 2.5rem;
    width: auto;
}

/* Only a header carrying both logos swaps between them; with one set it shows at every width. */
.site-logo--responsive .site-logo-compact { display: none; }

@media (max-width: 640px) {
    .site-logo--responsive .site-logo-wide { display: none; }
    .site-logo--responsive .site-logo-compact { display: block; }
}

.nav-menu {
    list-style: none;
    display: flex;
    gap: 1.5rem;
}

.nav-menu a {
    color: #fff;
    text-decoration: none;
    font-weight: 500;
}

.nav-menu a:hover { color: #fff; text-decoration: underline; }

.nav-toggle {
    display: none;
    flex-direction: column;
    gap: 5px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 4px;
}

.nav-toggle span {
    display: block;
    width: 24px;
    height: 2px;
    background: #fff;
    border-radius: 2px;
}

/* Hero */
.hero {
    position: relative;
    background-color: var(--color-carton);
    color: #fff;
    text-align: center;
    padding: 5rem 1.25rem;
    overflow: hidden;
}

.hero-bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0.35;
}

.hero-content {
    position: relative;
    z-index: 1;
}

.hero-content h1 {
    font-size: clamp(2rem, 5vw, 3.5rem);
    font-weight: 800;
    line-height: 1.15;
    margin-bottom: 1rem;
}

.hero-sub {
    font-size: 1.2rem;
    margin-bottom: 2rem;
    opacity: 0.9;
}

/* Buttons
   Two levels only: primary for the single action a page is asking for, secondary for everything
   else. Both share a footprint so they can sit side by side without one shifting the baseline.
   Borders are transparent on the primary rather than absent, so the two are the same height. */
.btn-primary,
.btn-secondary {
    display: inline-block;
    padding: 0.75rem 2rem;
    border-radius: 4px;
    border: 2px solid transparent;
    font-weight: 700;
    font-size: 1rem;
    text-decoration: none;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease, border-color .15s ease,
                transform .18s ease, box-shadow .18s ease;
}

/* Lift on hover, adapted from the DLC payments primary button. Scale is dialled back from 1.05 to
   1.03 — a text button moving 5% softens its glyphs mid-transition — and the shadow is tinted with
   --color-ink rather than neutral black, which reads as part of this palette rather than generic
   Material. Unlike the original, transform and box-shadow are in the transition above, so it eases
   rather than snapping. */
.btn-primary:hover,
.btn-secondary:hover {
    transform: scale(1.03) translateY(-1px);
    box-shadow: 0 6px 14px rgb(18 32 31 / .22), 0 2px 4px rgb(18 32 31 / .18);
}

/* Settle back down on press, so the button acknowledges the click. */
.btn-primary:active,
.btn-secondary:active {
    transform: scale(1) translateY(0);
    box-shadow: 0 1px 2px rgb(18 32 31 / .2);
}

@media (prefers-reduced-motion: reduce) {
    .btn-primary,
    .btn-secondary { transition: background-color .15s ease, color .15s ease, border-color .15s ease; }

    .btn-primary:hover,
    .btn-secondary:hover,
    .btn-primary:active,
    .btn-secondary:active { transform: none; }
}

.btn-primary {
    background: var(--color-berry);
    border-color: var(--color-berry);
    color: #fff;
}

.btn-primary:hover {
    background: var(--color-berry-dark);
    border-color: var(--color-berry-dark);
    color: #fff;
}

.btn-secondary {
    background: transparent;
    border-color: var(--color-berry);
    color: var(--color-berry);
}

.btn-secondary:hover {
    background: var(--color-berry);
    border-color: var(--color-berry);
    color: #fff;
}

/* On the teal fields both levels must invert. Berry on carton measures 1.26:1 — not merely muddy
   but unreadable, and far below the 3:1 that WCAG 1.4.11 requires of a control's own outline.
   .surface-dark is the general hook: put it on any panel carrying a brand color rather than paper.
   Scoping this to .hero and .site-footer alone was a bug — a teal panel that was neither rendered
   the un-inverted styling and failed silently. */
.hero .btn-primary,
.site-footer .btn-primary,
.surface-dark .btn-primary {
    background: var(--color-paper);
    border-color: var(--color-paper);
    color: var(--color-ink);
}

.hero .btn-primary:hover,
.site-footer .btn-primary:hover,
.surface-dark .btn-primary:hover {
    background: #fff;
    border-color: #fff;
    color: var(--color-ink);
}

/* White rather than --color-paper: paper on carton measures 4.34:1, and a 16px bold button is not
   "large text" under WCAG, so it would miss AA. White reaches 4.69:1. */
.hero .btn-secondary,
.site-footer .btn-secondary,
.surface-dark .btn-secondary {
    background: transparent;
    border-color: #fff;
    color: #fff;
}

.hero .btn-secondary:hover,
.site-footer .btn-secondary:hover,
.surface-dark .btn-secondary:hover {
    background: var(--color-paper);
    border-color: var(--color-paper);
    color: var(--color-ink);
}

/* Mission */
.mission {
    padding: 4rem 1.25rem;
    max-width: 760px;
}

/* The home page's calendar panel takes the mission's column rather than the full container, so
   the two line up and the panel doesn't read as a second hero. */
.home-calendar { max-width: 760px; }

/* Centred to sit under the centred hero; Find Food's panel keeps its left alignment. */
.home-calendar .calendar-callout { text-align: center; }

.mission h2 {
    font-size: 1.75rem;
    color: var(--color-carton-dark);
    margin-bottom: 1rem;
}

/* Distro calendars */
.page-head {
    padding: 3rem 1.25rem 0.5rem;
}

.page-head h1 { color: var(--color-carton-dark); }

.page-kicker {
    color: var(--color-muted);
    text-transform: uppercase;
    letter-spacing: .12em;
    font-size: .78rem;
    font-weight: 700;
}

.calendar-detail { padding-bottom: 4rem; }

.calendar-detail .btn-primary { margin-top: 1.5rem; }

/* Deliberately legible rather than fine print — it is the download's cost to the reader. */
.calendar-meta {
    margin-top: .6rem;
    color: var(--color-muted);
    font-size: .9rem;
}

.calendar-note,
.calendar-intro { margin-top: 1.5rem; max-width: 60ch; }

.calendar-back { margin-top: 2.5rem; }

.calendar-missing {
    margin-top: 1.5rem;
    color: var(--color-muted);
}

.calendar-card {
    display: block;
    margin-top: 2rem;
    padding: 1.75rem 1.5rem;
    border: 2px solid var(--color-carton-light);
    border-radius: 8px;
    background-color: #fff;
    text-decoration: none;
    color: var(--color-text);
}

.calendar-card:hover {
    border-color: var(--color-berry);
    color: var(--color-text);
}

.calendar-card-label {
    display: block;
    color: var(--color-muted);
    text-transform: uppercase;
    letter-spacing: .12em;
    font-size: .72rem;
    font-weight: 700;
}

.calendar-card-month {
    display: block;
    margin-top: .35rem;
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--color-carton-dark);
}

.calendar-past-head {
    margin-top: 3rem;
    font-size: 1.1rem;
    color: var(--color-carton-dark);
}

.calendar-list {
    list-style: none;
    margin-top: .75rem;
    padding-bottom: 4rem;
}

.calendar-list li { padding: .4rem 0; }

/* Find Food listings */
/* Landmarks. The page is a long single column on a phone and every section used to start with
   the same weight of text, so there was nothing to scan by -- you had to read to find out where
   you were. The rule above each one is what does most of the work; it is carton-mid at 3:1 rather
   than carton-light, for the same reason the calendar's grid lines are. */
.section-head {
    margin-top: 2.75rem;
    margin-bottom: .75rem;
    padding-top: .6rem;
    border-top: 2px solid var(--color-carton-mid);
    font-size: .95rem;
    font-weight: 800;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--color-carton-dark);
}

/* The qualifier that is not the label -- "September 2026" under "Distros by day". Kept out of the
   uppercase, which is hard to read at length and does a date no favours. */
.section-head-note {
    display: block;
    margin-top: .2rem;
    font-size: .95rem;
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
    color: var(--color-muted);
}

/* The first one on the page sits right under the now board, which already has its own rule. */
.now-board + .container > .section-head:first-child { margin-top: 1.5rem; }

.place-list {
    list-style: none;
    margin-top: 1rem;
    padding-bottom: 1rem;
}

.place {
    padding: .9rem 0;
    border-bottom: 1px solid var(--color-carton-light);
}

.place-name {
    display: block;
    font-weight: 700;
    font-size: 1.05rem;
}

/* When comes before where: someone checking a phone on the street needs to know if it is
   happening now before they care about the cross street. */
.place-when {
    display: block;
    color: var(--color-text);
}

.place-where {
    display: block;
    color: var(--color-muted);
    font-size: .92rem;
}

.place-detail { padding-bottom: 4rem; }

.place-facts { margin-top: 1.5rem; }

.place-facts dt {
    color: var(--color-muted);
    text-transform: uppercase;
    letter-spacing: .1em;
    font-size: .72rem;
    font-weight: 700;
    margin-top: 1.1rem;
}

.place-facts dd { margin-top: .2rem; }

/* Content pages (About, Privacy, ...). Rich text from the editor arrives as bare h2/p/ul, and the
   reset at the top of this file strips every margin and the list indent, so without this the
   paragraphs run together and bullets hang off the left edge. A measure of about 70 characters is
   what keeps a long page readable. */
.content-page { padding-bottom: 4rem; }

.prose { max-width: 70ch; margin-top: 1.25rem; }
.prose > * + * { margin-top: 1rem; }
.prose h2 {
    margin-top: 2.25rem;
    font-size: 1.35rem;
    color: var(--color-carton-dark);
}
.prose h3 { margin-top: 1.75rem; font-size: 1.1rem; }
.prose ul, .prose ol { padding-left: 1.4rem; }
.prose li + li { margin-top: .45rem; }

/* Groups page. One card per group, in the same white-on-paper card the calendar uses, so the
   groups read as the site's equals rather than as a list of links. auto-fill gives one column on
   a phone and two or three on a desktop without a breakpoint. */
.groups { padding-bottom: 4rem; }

.groups-intro { margin-top: 1rem; max-width: 60ch; }

.group-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
    gap: 1.25rem;
    margin-top: 2rem;
}

.group {
    padding: 1.5rem 1.25rem;
    border: 2px solid var(--color-carton-light);
    border-radius: 8px;
    background-color: #fff;
}

.group-head {
    display: flex;
    align-items: center;
    gap: .9rem;
}

/* Height-bound, not width-bound: the logos are every shape from a square badge to a wide
   wordmark, and a common height lines the names up. */
.group-logo {
    height: 3.5rem;
    width: auto;
    max-width: 7rem;
    object-fit: contain;
    flex-shrink: 0;
}

.group-name {
    font-size: 1.3rem;
    color: var(--color-carton-dark);
}

.group-about { margin-top: .9rem; }

.group .place-facts { margin-top: .5rem; }

/* Wish lists and donate pages are long unbroken addresses; let them wrap anywhere rather than
   run out of the card. */
.group dd { overflow-wrap: anywhere; }

.group-when {
    display: block;
    color: var(--color-muted);
    font-size: .92rem;
}

/* Calendar callout on Find Food. Carries .surface-dark so the button inverts — without it the
   berry button on a carton panel lands at 1.26:1. */
.calendar-callout {
    margin-top: 2rem;
    padding: 1.75rem 1.5rem;
    border-radius: 8px;
    background-color: var(--color-carton);
    background-image: var(--paper-texture);
    background-repeat: repeat;
    background-blend-mode: multiply;
    color: #fff;
}

.calendar-callout-label {
    text-transform: uppercase;
    letter-spacing: .12em;
    font-size: .72rem;
    font-weight: 700;
}

.calendar-callout-month {
    margin-top: .2rem;
    font-size: 1.4rem;
    font-weight: 700;
}

.calendar-callout .btn-primary { margin-top: 1rem; }

.calendar-callout-meta {
    margin-top: .7rem;
    font-size: .88rem;
}

.calendar-callout-meta a { color: var(--color-carton-light); }

/* Find Food map */
.map-wrap { margin-top: 2rem; }

#food-map {
    height: 420px;
    border-radius: 8px;
    border: 1px solid var(--color-carton-light);
}

/* Leaflet paints its own controls and attribution; keep the page font so it does not look bolted on. */
.leaflet-container { font-family: var(--font-body); }

.map-filters {
    border: 0;
    padding: 0;
    margin-bottom: .9rem;
    display: flex;
    flex-wrap: wrap;
    gap: .4rem .9rem;
    align-items: center;
}

.map-filters legend {
    float: left;
    width: 100%;
    color: var(--color-muted);
    text-transform: uppercase;
    letter-spacing: .1em;
    font-size: .72rem;
    font-weight: 700;
    margin-bottom: .4rem;
}

.map-filters label {
    font-size: .9rem;
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    cursor: pointer;
}

.map-note {
    margin-top: .6rem;
    color: var(--color-muted);
    font-size: .85rem;
}

.map-popup-name { display: block; font-weight: 700; margin-bottom: .25rem; }
.map-popup-when { display: block; }
.map-popup-where,
.map-popup-offers { display: block; color: var(--color-muted); font-size: .88rem; }

@media (max-width: 640px) {
    #food-map { height: 320px; }
}

/* ===================================================================== the now board

   The most time-urgent thing the page knows, so it sits above everything and is identical at
   every width. Both caps in NowBoard exist for the narrow layout's height budget: a busy
   Saturday with five things open would otherwise push the day cards off a small screen. */

.now-board {
    background-color: var(--color-berry-light);
    border-bottom: 2px solid var(--color-berry);
    padding: .8rem 0 .9rem;
}

.now-board.is-quiet {
    background-color: var(--color-carton-light);
    border-bottom-color: var(--color-carton-mid);
}

.now-board-head {
    display: flex; align-items: baseline; justify-content: space-between; gap: .5rem;
    margin-bottom: .5rem;
}

.now-board-title { font-size: 1.1rem; margin: 0; color: var(--color-berry-dark); }
.now-board.is-quiet .now-board-title { color: var(--color-carton-dark); }

/* The stamp is not decoration: it is what stops a page restored from bfcache reading as current. */
.now-board-stamp { font-size: .72rem; color: var(--color-muted); white-space: nowrap; }

.now-list { list-style: none; margin: 0; padding: 0; }

/* Name and time only. Someone acting on "right now" needs to know what and when, and taps
   through for the rest; the compact row is what keeps the strip inside its height budget. */
.now-row {
    display: flex; align-items: baseline; justify-content: space-between; gap: .75rem;
    background-color: #fff;
    border: 1px solid var(--color-berry);
    border-radius: 6px;
    padding: .5rem .7rem;
    margin-bottom: .35rem;
    text-decoration: none;
    color: var(--color-ink);
}

.now-board.is-quiet .now-row { border-color: var(--color-carton-mid); }
.now-row-name { font-weight: 700; line-height: 1.25; }
.now-row-time { font-weight: 600; font-size: .88rem; color: var(--color-berry-dark); white-space: nowrap; }
.now-row-soon .now-row-time { color: var(--color-muted); }

.now-sub { font-weight: 700; font-size: .78rem; color: var(--color-muted); margin: .7rem 0 .35rem; }
.now-overflow { font-size: .8rem; color: var(--color-muted); margin: .1rem 0 0; }
.now-none { margin: 0; line-height: 1.5; }

/* ===================================================================== month grid

   Days are told apart by three cues at once, not by a hairline: each day is a filled tile, the
   tiles are separated by a gutter of bare paper, and the tile carries a 3:1 border. Any one of
   the three surviving -- a greyscale print, a washed-out screen in daylight, a 1px line lost to
   fractional device pixels -- is enough to still read the grid. The previous single carton-light
   border was 1.16:1 against the page and effectively invisible.

   border-collapse is separate, not collapse, because the empty leading and trailing cells opt out
   by dropping their fill and border. Under collapse those cells still share edges with their
   neighbours and the browser arbitrates which wins, so the month's ragged corners came back as
   half-drawn stubs. */

.calendar-scroll { overflow-x: auto; margin-top: 1rem; -webkit-overflow-scrolling: touch; }

.month {
    width: 100%;
    min-width: 44rem;
    table-layout: fixed;
    border-collapse: separate;
    border-spacing: 3px;
    font-size: .82rem;
}

.month th {
    text-align: left;
    padding: .4rem .5rem;
    color: var(--color-muted);
    text-transform: uppercase;
    letter-spacing: .1em;
    font-size: .68rem;
    border-bottom: 2px solid var(--color-carton-mid);
}

.month td {
    vertical-align: top;
    height: 5.5rem;
    padding: .35rem .4rem;
    /* background-color, never the background shorthand: the shorthand resets the paper texture
       the page blends over this. */
    background-color: var(--color-carton-light);
    border: 1px solid var(--color-carton-mid);
    border-radius: 4px;
}

/* Needs the td to outweigh ".month td", which sets the tile fill and border. As a bare class it
   loses on specificity and the month's padding cells render as blank tiles. */
.month td.month-empty { background-color: transparent; border-color: transparent; }
.month-num { display: block; font-weight: 700; color: var(--color-carton-dark); }

/* Today is a different colour of tile, not just a ring. Same border width as every other tile so
   nothing shifts by a pixel; the weight comes from the inset shadow. */
.month-today {
    background-color: var(--color-berry-light);
    border-color: var(--color-berry);
    box-shadow: inset 0 0 0 1px var(--color-berry);
}

.month-today .month-num { color: var(--color-berry-dark); }

/* Entries sit on paper inside the tinted tile, so "which day" and "what is on it" are different
   surfaces rather than two sizes of text on one. */
.month-item {
    display: block;
    margin-top: .25rem;
    padding: .2rem .3rem;
    background-color: var(--color-paper);
    border-radius: 3px;
    text-decoration: none;
    line-height: 1.25;
}

.month-item.is-open { background-color: var(--color-berry-light); box-shadow: inset 0 0 0 1px var(--color-berry); }
.month-item-name { display: block; font-weight: 600; font-size: .72rem; }
.month-item-time { display: block; color: var(--color-muted); font-size: .68rem; }
.month-overflow { display: block; margin-top: .25rem; font-size: .68rem; font-weight: 700; color: var(--color-berry-dark); }

/* ===================================================================== narrow: day board

   Hidden above the breakpoint, and the grid is hidden below it. The switch is a media query
   rather than a device sniff, so a narrow desktop window gets whichever actually fits. */

.day-board { display: none; }

.day-cards {
    display: flex;
    gap: .6rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    align-items: flex-start;      /* natural card heights; without this every card is as tall as
                                     the tallest in the month */
    padding: .8rem 0 1rem;
    scrollbar-width: none;
}

.day-cards::-webkit-scrollbar { display: none; }

.day-card {
    flex: 0 0 calc(100% - 1.5rem);
    scroll-snap-align: center;
    background-color: #fff;
    border: 1px solid var(--color-carton-mid);
    border-radius: 10px;
    padding: .8rem .85rem .9rem;
}

.day-card.is-today { border-color: var(--color-berry); box-shadow: inset 0 0 0 1px var(--color-berry); }

/* The heading ladder, in order. It was inverted before -- group headings were .72rem while the
   items inside them were .95rem -- which is why nothing read as a heading. */
.day-card-date { margin: 0; font-size: 1.1rem; line-height: 1.15; }
.day-card-dow { margin: .15rem 0 .7rem; font-size: .85rem; font-weight: 700; color: var(--color-muted); }
.day-card.is-today .day-card-dow { color: var(--color-berry-dark); }

.entry {
    display: flex;
    align-items: center;
    gap: .5rem;
    background-color: var(--color-paper);
    border: 1px solid var(--color-carton-light);
    border-radius: 8px;
    padding: .55rem .65rem;
    margin-bottom: .4rem;
}

.entry-link { flex: 1 1 auto; text-decoration: none; color: var(--color-ink); min-width: 0; }

/* Secondary to the name on purpose: tapping a distro should still reach its own page, where the
   address, offerings and access notes are. This is the shortcut to the pin, not a replacement. */
.entry-map {
    flex: 0 0 auto;
    font: inherit;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--color-berry-dark);
    background-color: #fff;
    border: 1px solid var(--color-carton-mid);
    border-radius: 6px;
    padding: .4rem .55rem;
    min-height: 2.4rem;
    cursor: pointer;
}

.entry-map:hover { border-color: var(--color-berry); }

/* The pin the map just opened, so the connection between the tap and the marker is visible when
   the page scrolls. */
.entry.is-targeted { border-color: var(--color-berry); box-shadow: inset 0 0 0 1px var(--color-berry); }

.entry.is-open { border-color: var(--color-berry); background-color: var(--color-berry-light); }
.entry-name { display: block; font-weight: 700; font-size: .92rem; line-height: 1.25; }
.entry-time { display: block; margin-top: .1rem; font-size: .85rem; font-weight: 600; color: var(--color-berry-dark); }

.entry-flag {
    display: inline-block; margin-left: .4rem;
    font-size: .68rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
    color: var(--color-berry-dark);
}

.day-empty { margin: 0; color: var(--color-muted); font-style: italic; }
.day-rest { list-style: none; margin: 0; padding: 0; }

.day-more {
    font: inherit; font-size: .85rem; font-weight: 700;
    width: 100%; text-align: left;
    background: none;
    border: 1px dashed var(--color-carton-mid);
    border-radius: 8px;
    padding: .55rem .65rem;
    min-height: 2.75rem;
    color: var(--color-berry-dark);
    cursor: pointer;
}

/* Sticky rather than fixed, so it never covers content on a short screen -- it comes to rest at
   the end of the page instead. */
.day-nav {
    position: sticky;
    bottom: 0;
    z-index: 5;
    display: flex;
    align-items: center;
    gap: .4rem;
    padding: .5rem 0 calc(.5rem + env(safe-area-inset-bottom, 0px));
    background-color: var(--color-paper);
    border-top: 1px solid var(--color-carton-mid);
}

.day-nav button {
    font: inherit; font-size: .85rem; font-weight: 700;
    border: 1px solid var(--color-carton-mid);
    background-color: #fff;
    color: var(--color-ink);
    border-radius: 8px;
    padding: .5rem .7rem;
    min-width: 2.75rem; min-height: 2.75rem;       /* 44px: the smallest reliable touch target */
    display: inline-flex; align-items: center; justify-content: center;
    cursor: pointer;
}

.day-nav-today { flex: 1 1 auto; }
.day-nav-month { background-color: var(--color-carton); border-color: var(--color-carton); color: #fff; }
.day-nav button[disabled] { opacity: .4; }

/* ---------------------------------------------------------------- dot month

   A planner wants the shape of the month, not the names, so the cell carries density instead of
   text. That is what lets seven columns fit a 360px screen -- the full grid cannot, and side-
   scrolling a table is the problem this layout exists to avoid. */

.dot-month { padding: .8rem 0 1rem; }
.dot-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.dot-head { text-align: center; font-size: .68rem; font-weight: 700; color: var(--color-muted); padding-bottom: .3rem; }

.dot-cell {
    aspect-ratio: 1 / 1;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .2rem;
    background-color: var(--color-carton-light);
    border: 1px solid var(--color-carton-mid);
    border-radius: 6px;
    font: inherit; font-size: .85rem; font-weight: 700;
    color: var(--color-carton-dark);
    padding: 0;
    cursor: pointer;
}

.dot-cell.is-empty { background-color: transparent; border-color: transparent; cursor: default; }

/* Days already gone. Kept visible so the month still reads as a month, but plainly out of reach --
   there is nothing on them anyone can still go to. */
.dot-cell.is-past {
    background-color: transparent;
    border-style: dashed;
    border-color: var(--color-carton-light);
    color: var(--color-muted);
    opacity: .55;
    cursor: default;
}

.dot-cell.is-past .dot { background-color: var(--color-muted); }

.dot-cell.is-today {
    background-color: var(--color-berry-light);
    border-color: var(--color-berry);
    box-shadow: inset 0 0 0 1px var(--color-berry);
    color: var(--color-berry-dark);
}

.dot-cell[aria-pressed="true"] {
    background-color: var(--color-carton);
    border-color: var(--color-carton-dark);
    color: #fff;
}

.dots { display: flex; gap: 2px; height: .32rem; align-items: center; }
.dot { width: .32rem; height: .32rem; border-radius: 50%; background-color: var(--color-berry); }
.dot-cell[aria-pressed="true"] .dot { background-color: #fff; }

.dot-detail { margin-top: 1rem; }
.dot-detail h3 { margin: 0 0 .5rem; font-size: 1rem; }

/* ---------------------------------------------------------------- the switch */

@media (max-width: 46rem) {
    .day-board { display: block; }
    .calendar-scroll { display: none; }
}

/* Distros and fridges side by side once there is room for two readable columns. */
.place-columns { display: block; }

@media (min-width: 900px) {
    .place-columns {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 0 2.5rem;
        align-items: start;
    }
}

/* Phones get centred text: the list is read at arm's length, one item at a time. */
@media (max-width: 640px) {
    .page-head,
    .calendar-intro,
    .place { text-align: center; }

}

/* A real target inside a Leaflet popup, which is a cramped place -- someone taps this standing on
   a street, probably one-handed. */
.map-popup-directions {
    display: inline-block;
    margin-top: .5rem;
    padding: .45rem .7rem;
    background-color: var(--color-berry);
    color: #fff !important;
    font-weight: 700;
    font-size: .82rem;
    text-decoration: none;
    border-radius: 6px;
}

.map-popup-directions:hover { background-color: var(--color-berry-dark); color: #fff !important; }

.map-popup-open {
    display: block;
    font-weight: 700;
    color: var(--color-berry-dark);
}

/* Available to screen readers, out of the visual flow — used for the calendar's caption. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* More resources */
.extras { padding-bottom: 3rem; }

.extras-list {
    list-style: none;
    margin-top: 1rem;
    max-width: 60ch;
}

.extras-list li {
    padding: .5rem 0;
    border-bottom: 1px solid var(--color-carton-light);
}

/* Corrections prompt. .surface-dark so the button inverts against the brand colour — berry on
   carton is 1.26:1 and unreadable. */
.submit-cta {
    margin-top: 1rem;
    padding: 3rem 0;
    background-color: var(--color-carton-dark);
    background-image: var(--paper-texture);
    background-repeat: repeat;
    background-blend-mode: multiply;
    color: #fff;
    text-align: center;
}

.submit-cta h2 { margin-bottom: .5rem; }
.submit-cta p { margin-bottom: 1.5rem; color: var(--color-carton-light); }

/* Footer */
.site-footer {
    background-color: var(--color-carton-darker);
    color: var(--color-carton-light);
    padding: 2rem 0;
    text-align: center;
    font-size: 0.9rem;
}

.site-footer a { color: var(--color-carton-light); }

.footer-tagline { margin-bottom: 0.75rem; }

/* Editor-managed list, so it has to wrap rather than overflow when someone adds a seventh link. */
.footer-links {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.5rem 1.25rem;
    margin-bottom: 0.75rem;
}

.footer-contact { margin-bottom: 0.75rem; }

.footer-legal {
    color: var(--color-carton-light);
    opacity: 0.75;
    font-size: 0.85rem;
}

/* Mobile nav */
@media (max-width: 640px) {
    .nav-toggle { display: flex; }

    .nav-menu {
        display: none;
        flex-direction: column;
        gap: 0.5rem;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        background: var(--color-carton);
        padding: 1rem 1.25rem;
        z-index: 100;
    }

    .nav-menu.open { display: flex; }

    .site-header { position: relative; }
}
