/**
 * Surf Shack — declare the `--ss-*` token family.
 *
 * THE FINDING: the site has 64 KB of CSS in the WordPress Customizer's Additional CSS
 * field (`<style id="wp-custom-css">`, 414 rules), and 215 of those rules reference a
 * `--ss-*` token family — `--ss-deep-teal`, `--ss-text-dark`, `--ss-text-muted` and
 * friends — that **is declared nowhere at all**. Every single use is
 * `var(--ss-thing, #hardcodedfallback)`, so the site has been running on the fallbacks
 * since the day they were written.
 *
 * CORRECTION, made after the first attempt shipped and measured as unchanged: the
 * Customizer CSS DOES declare them, in a `:root` block headed "Surf Shack Brand Color
 * Overrides" that my first search missed because I only grepped for `var()` USES, not
 * declarations. And because that CSS prints last in `wp_head`, its `:root` beat this
 * file's at equal specificity. Hence `html:root` below — (0,1,1) against (0,0,1), which
 * wins without reaching for !important on a custom property.
 *
 * The lesson is the same one the header button taught two hours ago: deployed is not
 * applied. Both times the file was correct, present and losing, and both times only
 * re-measuring the rendered page caught it.
 *
 * Declaring the family here is therefore the highest-leverage correction available:
 * one block moves 215 rules onto the system without touching the Customizer CSS, and
 * it lives in the plugin, so it travels to production with a plugin upload — which the
 * Customizer CSS does NOT (see the note at the bottom).
 *
 * Only tokens that fix a MEASURED failure or a stated house rule are declared. Borders
 * and tints (`--ss-soft-mint`, `--ss-mint-light`, `--ss-border-soft`, `--ss-sandy-yellow`)
 * are deliberately left on their fallbacks: changing those is cosmetic drift, not
 * enforcement, and `--ss-soft-mint` doubles as a focus ring that a lighter value would
 * only weaken.
 *
 * @package SurfShack\Core
 */

html:root {
  /* Text at 3.88:1 — fails AA as small text. Used 72 times, as text AND as a fill under
     white, and #357B7D is the same hue fixed for both: 4.91:1 either way. Repairs
     .ssr-pp-prog-active (12px/700), .ssr-pp-bag-qty (16px/700) and every teal label
     across the account and booking screens at once. */
  --ss-deep-teal: #357B7D;

  /* Was #15325b — the navy from the site chrome, doing duty as body ink on product
     screens. Passes contrast, but it is not the system's ink and it made the picker
     read as a different product to everything beside it. */
  --ss-text-dark: #1F3E4A;

  /* Was #4a6b7e. On-system muted, and 4.94:1 on white rather than sitting just above
     the line. */
  --ss-text-muted: #5A7482;

  /* Was #c0392b. The site went to ONE red, #B42318, in a sweep of 27 files — and this
     token quietly kept a 28th outside it, because nothing declared it. */
  --ss-error: #B42318;

  /* Was #f09956, used as BOTH a fill under white text and as text on white: 2.24:1 in
     both directions. Nick, 15 Aug: orange buttons carry white text, so the fill moves.
     #C25700 is the same hue at 4.51:1 — and it fixes the text role in the same stroke. */
  --ss-sunset-orange: #C25700;
}

/* ---------------------------------------------------------------------------
 * The pass picker paints prices in the card's CODING hue, which is a graphics
 * value, not a text value: "from $8" measured 1.89:1 in volleyball yellow and
 * "from $40" measured 2.24:1 in Open Flow orange.
 *
 * `--ssr-card-ink` is emitted next to `--ssr-card-accent` by ssr_pp_ink() in
 * booking-helpers.php. The accent keeps every role where 3:1 is the bar — the
 * card rule, the hover border, the selected state. Only the text moves.
 *
 * !important and the doubled class are both required: the Customizer CSS prints
 * last in wp_head and already carries !important on these selectors, so nothing
 * gentler can win. See ss-layout-fixes.css for the same lesson learned the hard
 * way on the header button.
 * ------------------------------------------------------------------------- */
.ssr-pp .ssr-pp-type-card .ssr-pp-type-from,
.ssr-pp .ssr-pp-type-from {
  color: var(--ssr-card-ink, #357B7D) !important;
}
.ssr-pp .ssr-pp-var-card .ssr-pp-var-price,
.ssr-pp .ssr-pp-var-price {
  color: var(--ssr-card-ink, #357B7D) !important;
}

/* ---------------------------------------------------------------------------
 * FLAGGED, NOT FIXED — for whoever owns the cutover.
 *
 * The Customizer CSS is a database row (`custom_css` post), not a file. The
 * production plan moves code as a plugin upload, so **these 64 KB do not travel
 * with it**. Anything styled only by that field — the whole pass picker, chunks
 * of the account screens — will land on production unstyled unless the Additional
 * CSS is migrated deliberately as part of the content release.
 * ------------------------------------------------------------------------- */

/* ===========================================================================
 * THE `--ssx-*` FAMILY — the same finding as `--ss-*` above, in a second module.
 *
 * `includes/modules/public-availability/public-availability.php` declares its own
 * `--pa-*` tokens on `.ssr-pa`, and every one of them is written as
 * `var(--ssx-something, #hardcodedfallback)` — deliberately, as a hook so the module
 * can inherit a site-wide palette instead of inventing one. The comment in that file
 * says as much: *"Every one of those parallel values is gone -- brand is --ssx-brand
 * now."*
 *
 * Measured on the rendered /availability/ page: **nine uses of `--ssx-*`, zero
 * declarations.** The hook was built and never plugged in, so the module has been
 * running on its fallbacks since it shipped — which is why it renders in values that
 * exist nowhere else on the site.
 *
 * Declaring them here is worth far more than overriding rules one at a time: nine
 * declarations reach 63 rules, and they reach any future module that uses the same
 * hook. `html:root` for the same reason as the block above — the Customizer CSS
 * carries its own `:root` and prints last.
 * ------------------------------------------------------------------------- */
html:root {
  /* Body ink, unchanged — the module already picked the system value as its fallback. */
  --ssx-ink: #1F3E4A;

  /* Was #4A6B7E: a fourth blue-grey, and the SECOND-strongest of three text levels the
     system does not have. It paints `.slot .slab` ("Open"), the table headers and the
     hour column, all primary labels, so they take the system ink. That also restores
     the hierarchy against `.cnt` below, which the two near-identical greys had flattened. */
  --ssx-ink-2: #1F3E4A;

  /* Was #7A8A92 — 3.57:1 on white, and it FAILS AA at every size the module uses it:
     "8 spots left" (12px/500), "Reserved" (14px/600), "Sat, Aug 15" (14px/500), the
     fieldset legends and the timestamp. Five distinct failures, one token. #5A7482 is
     the system muted at 4.94:1. */
  --ssx-ink-muted: #5A7482;

  /* Was #EEF3F6, a cool grey that is nearly invisible as a table rule. One hairline. */
  --ssx-line: #D8E6E6;

  /* Already on-system; declared so nothing depends on a fallback. */
  --ssx-mint: #CBE5DC;
  --ssx-brand: #3D8D90;
  --ssx-reversed: #FFFFFF;

  /* Was #F3FAF7 — a fifth off-white. --recessed is the one the app uses. */
  --ssx-wash: #F4F9F8;

  /* Was #B54708. #B85E10 is the activity-open ink, which is the hue this is signalling
     ("almost full"), and it clears both bars, 4.52:1 as text, comfortably past 3:1 as
     the ring graphic it is actually used for. */
  --ssx-warn: #B85E10;
}

/* ---------------------------------------------------------------------------
 * /availability/ — two things the tokens cannot reach.
 *
 * 1. TWO HUNDRED AND NINETY-FOUR UNDERLINED BLUE LINKS.
 *
 *    Every cell in the grid is `<a class="slot">` wrapping a label and a count, and
 *    the module styles `.slab` and `.cnt` but never styles the ANCHOR. So all 294 of
 *    them fall through to the browser default: #0000EE and a permanent underline.
 *    That is the entire visual noise of that screen — a table where every cell is
 *    shouting.
 *
 *    That it was an oversight rather than a decision is provable from their own CSS:
 *    `a.slot:hover .slab{text-decoration:underline}` only makes sense if the resting
 *    state is NOT underlined. The hover rule was written; the base rule was not.
 *
 *    `color:inherit` rather than a value, so `.slab` and `.cnt` keep the colours the
 *    module gives them and the hover rule still does its job.
 *
 * 2. RADIUS. `--pa-r` is a literal 10px, not an `--ssx-*` hook, so it needs its own
 *    line. The product system moved to 4px on 15 Aug.
 * ------------------------------------------------------------------------- */
.ssr-pa a.slot,
.ssr-pa a.slot:visited {
  text-decoration: none;
  color: inherit;
}
.ssr-pa a.slot:focus-visible {
  outline: 3px solid #3D8D90;
  outline-offset: 2px;
  border-radius: 4px;
}
.ssr-pa { --pa-r: 4px; }

/* ---------------------------------------------------------------------------
 * /availability/ — the view switcher, made consistent with everything else.
 *
 * 3. RADIUS, corrected. `.ssr-pa{--pa-r:4px}` above was the right idea at the wrong
 *    specificity: their declaration is also `.ssr-pa` and prints inline, after this
 *    file, so at (0,1,0) each it wins on source order and `--pa-r` measured 10px
 *    unchanged. `.ssr-pa.ssr-pa` is (0,2,0), selects the same element, and wins.
 *
 * 4. THE SELECTED VIEW WAS THE WRONG COLOUR. `.ssr-pa-view[aria-pressed="true"]` fills
 *    with `--pa-ink` — near-black. Everywhere else on the site a selected control is
 *    teal: the owner console's nav and filter chips, the staff app's tabs. Near-black
 *    reads as "disabled" or "heading", not "this one". White on --brand-ink is 4.91:1.
 *
 * 5. THREE PILLS BECOME ONE CONTROL. Day / Week / Month and ‹ / Today / › are each a
 *    one-of-N choice rendered as separate floating buttons with a 6px gap — the same
 *    thing Nick called messy on the Orders screen. Same fix: gap to zero, shared
 *    borders, ends rounded. It reads as one switch rather than three buttons that
 *    happen to be adjacent.
 * ------------------------------------------------------------------------- */
.ssr-pa.ssr-pa { --pa-r: 4px; }

.ssr-pa .ssr-pa-view[aria-pressed="true"] {
  background: #357B7D;
  border-color: #357B7D;
  color: #fff;
}

.ssr-pa .ssr-pa-views,
.ssr-pa .ssr-pa-nav { gap: 0; }
.ssr-pa .ssr-pa-views > button,
.ssr-pa .ssr-pa-nav > button {
  border-radius: 0;
  margin-left: -1px;
  position: relative;
}
.ssr-pa .ssr-pa-views > button:first-child,
.ssr-pa .ssr-pa-nav > button:first-child {
  margin-left: 0;
  border-top-left-radius: 4px;
  border-bottom-left-radius: 4px;
}
.ssr-pa .ssr-pa-views > button:last-child,
.ssr-pa .ssr-pa-nav > button:last-child {
  border-top-right-radius: 4px;
  border-bottom-right-radius: 4px;
}
/* The selected segment owns the borders it shares with its neighbours. */
.ssr-pa .ssr-pa-view[aria-pressed="true"],
.ssr-pa .ssr-pa-views > button:hover,
.ssr-pa .ssr-pa-nav > button:hover { z-index: 1; }

/* ---------------------------------------------------------------------------
 * 6. /availability/ ON A PHONE. Measured at 390px: the page pushed 10-30px sideways
 *    through `.ssr-pa-main`, `.ssr-pa`, `.page-content`, `.site-main` and the theme's
 *    `h1.entry-title`.
 *
 *    It is not a bug so much as arithmetic: the grid is an hour column plus six
 *    activity columns. There is no width at which that fits a 390px screen, and the
 *    module's own mobile rules (which reorder the title and view switcher) do not
 *    change the column count.
 *
 *    The fix for a wide data table on a narrow screen is to let the TABLE scroll, not
 *    the page. A page that scrolls sideways loses the reader's place in both axes;
 *    a table that scrolls sideways is a table you swipe. The wrappers are capped so
 *    the overflow stops at the grid instead of travelling up to <body>.
 *
 *    `overscroll-behavior-x: contain` so swiping to the end of the grid does not then
 *    start swiping the page — the thing that makes a scrollable table feel broken.
 * ------------------------------------------------------------------------- */
.ssr-pa .ssr-pa-main {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}
.ssr-pa.ssr-pa, .ssr-pa .ssr-pa-main { max-width: 100%; }

/* ---------------------------------------------------------------------------
 * 7. THE HOVER STATE. Nick: "hover state is still underline."
 *
 * Their rule is `a.slot:hover .slab{text-decoration:underline;color:var(--pa-ink)}`,
 * and it underlines BOTH lines of the cell — because `.cnt` is nested inside `.slab`
 * rather than beside it, so the decoration propagates to the child. That is why the
 * hover reads so heavily: it is not one underline, it is two.
 *
 * Removing it is not enough on its own. The colour half of that rule became a no-op
 * when `--ssx-ink-2` folded into ink above — `.slab` is ALREADY `--pa-ink`, so once
 * the underline goes there is no hover feedback left at all, on a grid where every
 * cell is a booking link.
 *
 * So the affordance moves rather than disappears:
 *
 *   · the label turns teal — the standard "this is a link" signal, and it reads at a
 *     glance without adding a line of ink to every hovered cell;
 *   · the cell takes a soft tint, painted with a 6px box-shadow spread rather than
 *     padding, because `.slot` is a flex row whose spacing is set by the <td> — a
 *     shadow tints the cell without moving a single pixel of the grid.
 *
 * `.cnt` deliberately stays muted, so the two-level hierarchy inside the cell holds up
 * in the hover state as well as at rest.
 * ------------------------------------------------------------------------- */
.ssr-pa a.slot {
  border-radius: 4px;
  transition: background-color .12s linear, box-shadow .12s linear;
}
.ssr-pa a.slot:hover .slab,
.ssr-pa a.slot:focus-visible .slab {
  text-decoration: none;
  color: #357B7D;
}
.ssr-pa a.slot:hover {
  background: var(--pa-wash, #F4F9F8);
  box-shadow: 0 0 0 6px var(--pa-wash, #F4F9F8);
}
@media (prefers-reduced-motion: reduce) {
  .ssr-pa a.slot { transition: none; }
}


/* ===========================================================================
 * /account/bookings/ — the split layout was firing on the wrong axis.
 *
 * Nick, 15 Aug: "fix awkward spacing on account bookings page." The month title
 * wrapping to two lines, the weekday labels not lining up with their columns, and
 * day cells at three different heights are all one bug with one cause.
 *
 * WHAT IS ACTUALLY HAPPENING. The screen is a two-column split:
 *
 *     #ssr-bookings-listing .ssr-bl-split { grid-template-columns: 2fr 3fr }
 *     @media (max-width: 760px) { .ssr-bl-split { grid-template-columns: 1fr } }
 *
 * So the author already built a stacked layout for when there isn't room. It never
 * fires. The media query asks the VIEWPORT, and the component does not live in the
 * viewport — it lives inside `.ssr-acct-wrap`, which is `max-width: 760px`. On a
 * 1677px screen the query reports "plenty of room" and the two-column layout runs
 * inside a box that is exactly at the breakpoint.
 *
 * And `2fr 3fr` cannot deliver 2:3 there, because an `fr` track has a min-content
 * floor. The booking row is a chain of `white-space:nowrap` fields with min-widths
 * (170 + 110 + 120 from one sheet, 104 + 68 + 160 from another), so column 1 claims
 * 652.75px of a 740px space. Measured on the live page:
 *
 *     .ssr-bl-split   459..1219   760 wide
 *     .ssr-split-list 459..1111   652.75   <- took nearly all of it
 *     .ssr-split-cal  1131..1316  184.58   <- and overflowed 97px past the container
 *
 * 184px, minus 14px padding each side and 6 gaps, is ~20px per weekday column. That
 * is why "August 2026" wraps, why the weekday labels crowd, and why the columns come
 * out at seven different widths (18.2 / 20.8 / 17.8 / 21.3 / 18.4 / 18.0 / 28) —
 * `repeat(7, 1fr)` has the same min-content floor, so the Saturday column, which
 * holds the dots for the 15th, is 10px wider than Tuesday.
 *
 * THE FIX is to ask the right question. A container query measures the component's
 * own box, which is the thing that is actually 760px:
 *
 *   - Below 880px of container, use the stacked layout the author already wrote.
 *   - Above it — if the account measure is ever widened — the two-column split comes
 *     back on its own, with no breakpoint to remember.
 *
 * 880 rather than their 760: the row needs ~540px at its natural width and a usable
 * calendar needs ~300, plus the gap. At 760 the two-column version can only fit by
 * truncating a guest's name, which is not a trade worth making on the screen whose
 * whole job is telling you who is booked.
 *
 * `minmax(0, 1fr)` on the stacked track for the same min-content reason as above.
 *
 * The doubled class throughout: their rules carry `#ssr-bookings-listing`, and they
 * print in the body from the shortcode, so they land after this enqueued sheet. Same
 * ID plus a doubled class wins on specificity rather than on !important.
 * ======================================================================== */
#ssr-bookings-listing { container-type: inline-size; container-name: ssbook; }

@container ssbook (max-width: 880px) {
  #ssr-bookings-listing .ssr-bl-split.ssr-bl-split {
    grid-template-columns: minmax(0, 1fr);
    gap: 22px;
  }
  /* Left-aligned under the list rather than stretched across it. A month grid pulled
     to 760px would have 100px cells and read as a wall calendar. */
  #ssr-bookings-listing .ssr-split-cal.ssr-split-cal { max-width: 340px; }
}

/* Seven equal columns, whatever the dots do. `minmax(0, 1fr)` removes the min-content
   floor that made Saturday 28px and Tuesday 17.8px. */
#ssr-bookings-listing .ssr-cal-mini .ssr-cal-grid.ssr-cal-grid {
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 3px;
}

/* One cell height for every day of the month. It was 34px for an empty day, 47px for
   one booking's dots and 59px where the dots wrapped to a second row, which is what
   makes the grid look buckled. 46px holds a day number and two rows of dots, so a busy
   day and a quiet one are the same size. The dot strip is capped at two rows and clips
   past that, the dots are a density hint, and the day itself opens the detail. */
#ssr-bookings-listing .ssr-cal-mini .ssr-cal-day.ssr-cal-day { min-height: 46px; }
#ssr-bookings-listing .ssr-cal-mini .ssr-cal-dots.ssr-cal-dots {
  max-height: 12px;
  overflow: hidden;
}

/* The month arrows were 44x44 — the mobile tap floor — inside a 155px grid, which is
   most of the header's width and why the title had nowhere to go. 34px keeps a real
   target on a screen whose primary device is a phone while leaving the title one line. */
#ssr-bookings-listing .ssr-cal-head.ssr-cal-head button {
  min-width: 34px;
  min-height: 34px;
  font-size: 14px;
}

/* Let the two soft fields give way before the row does. Both are `nowrap` with a
   min-width, so in a flex row they refuse to shrink and push the row past its column
   instead. The rider already had `text-overflow: ellipsis` that could never fire. */
#ssr-bookings-listing .ssr-bl-card .ssr-bl-svc.ssr-bl-svc {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
#ssr-bookings-listing .ssr-bl-card .ssr-bl-rider.ssr-bl-rider { min-width: 0; }


/* ===========================================================================
 * THE BOOKING GRID HAD NO COLUMNS.
 *
 * Nick: "put book calendar inside a grid." /book/ and /availability/ render the same
 * `.ssr-pa` component — a table of six services across, by hour down.
 *
 * Measured on the live table: every cell is
 *
 *     border-top 0 · border-right 0 · border-bottom 1px #D8E6E6 · border-left 0
 *
 * Horizontal rules only. So the six service columns have nothing between them, and
 * with "Open / 8 spots left" repeating across all six at the same size, there is no
 * way to tell at a glance which column your eye is in. It is a table drawn as a list.
 *
 * A 1px rule between columns is the whole fix. `border-collapse` is already `separate`,
 * so a left border on every cell after the first draws exactly one line per boundary
 * and nothing doubles up. It also separates the hour column from the data, which is the
 * boundary that matters most — that is the axis you read against.
 *
 * WHILE HERE: the table's own outer border was #CBE5DC, the mint. On white that is
 * 1.28:1 — the card edge was there in the CSS and invisible on screen, which is the
 * other half of "not in a grid": no bounded object, no columns. Moved to the system
 * hairline, which is what every other rule in the table already uses, so the box and
 * its insides finally agree.
 *
 * Doubled class because the component's CSS prints in the body after this sheet.
 * ======================================================================== */
.ssr-pa .ssr-pa-dt.ssr-pa-dt { border-color: #D8E6E6; }
.ssr-pa .ssr-pa-dt.ssr-pa-dt td + td,
.ssr-pa .ssr-pa-dt.ssr-pa-dt th + th { border-left: 1px solid #D8E6E6; }


/* ---------------------------------------------------------------------------
 * THE GREY BOXES ON THE TIME SLOTS — a browser default in a booking grid.
 *
 * Nick: "fix the gray bg on the time slots." Measured on /book/: every slot computes
 *
 *     background-color: #F0F0F0    color: #000000
 *
 * which is Chrome's `buttonface` and `buttontext`. Nothing on the site chose either.
 *
 * The reason it shows here and not on /availability/ is that the two pages build the
 * same component from different elements. /availability/ renders `<a class="slot">`,
 * and an anchor has no default fill. /book/ renders `<button class="slot is-pick">`
 * because the slot has to open the picker, and a button does.
 *
 * The component already anticipated most of this — `.ssr-pa .slot.is-pick` resets
 * `border`, `font`, `cursor` and `appearance`. It just never reset `background`, and
 * `appearance:none` does not remove the fill, only the native chrome. So one missing
 * declaration put a grey box behind all 21 slots.
 *
 * `color:inherit` goes with it. The black never showed, because `.slab` and `.cnt` set
 * their own colours — but it is the same default sitting one rule away from being seen.
 *
 * Doubled `.is-pick` to clear their (0,3,0) rule, which prints in the body after this
 * sheet. The hover is doubled again so it outranks the transparent it has to override,
 * and it is the same treatment `a.slot` already gets above, so the two pages now
 * behave identically under the pointer as well as at rest.
 * ------------------------------------------------------------------------- */
.ssr-pa .slot.is-pick.is-pick {
  background: transparent;
  color: inherit;
}
.ssr-pa .slot.is-pick.is-pick:hover,
.ssr-pa .slot.is-pick.is-pick:focus-visible {
  background: var(--pa-wash, #F4F9F8);
  box-shadow: 0 0 0 6px var(--pa-wash, #F4F9F8);
}
.ssr-pa .slot.is-pick.is-pick:hover .slab,
.ssr-pa .slot.is-pick.is-pick:focus-visible .slab { color: #357B7D; }


/* ---------------------------------------------------------------------------
 * THE BOOKING CALENDAR ON THE LAYOUT GRID.
 *
 * Nick: "i meant a layout grid, like 1200px or whatever the system is set to."
 *
 * WHAT THE SYSTEM IS ACTUALLY SET TO, measured at a 1700px viewport, because the
 * answer turned out to be "five different things":
 *
 *     1450px   Elementor's global container — the header and every page container
 *     1220px   the footer's own containers (see section 1 of ss-layout-fixes.css)
 *     1180px   `.ssr-own` — the owner console, the one surface that declares a measure
 *     1140px   Hello Elementor's content cap, which is what holds /availability/
 *     1100px   a container on /passes/
 *
 * So there is no single declared grid to snap to, and picking one is a decision. 1180
 * is the right one here: /book/ is a product surface, not a marketing page, and 1180 is
 * the number the product side already uses. Taking Elementor's 1450 would have made the
 * booking grid the widest thing on the site.
 *
 * Measured before: `.ssr-pa` rendered at 1450px on /book/ — six service columns at
 * ~220px each, spread across the full Elementor container with nothing else on the page
 * to measure against.
 *
 * Capping the ROOT rather than the table, so the day/week/month switch, the service
 * toggles and the grid all land on the same two edges. Centred with auto margins, and
 * `max-width` not `width`, so under 1180 it stays fluid and the existing horizontal
 * scroller inside `.ssr-pa-main` keeps doing its job on a phone.
 *
 * /availability/ renders the same component and will NOT move: Hello Elementor caps its
 * ancestor at 1140px, tighter than this. The two pages end up 40px apart. Unifying them
 * means releasing the theme cap on that page, which is a change to a page Nick has not
 * asked about — flagged rather than done.
 * ------------------------------------------------------------------------- */
.ssr-pa.ssr-pa {
  max-width: 1180px;
  margin-left: auto;
  margin-right: auto;
}


/* ---------------------------------------------------------------------------
 * MOBILE — STACK THE RING AND THE TEXT.
 *
 * Nick: "on mobile, stack the ring and text."
 *
 * `.slot` is `display:flex; align-items:center; gap:10px` — the capacity ring beside
 * the label. That is right on a wide screen and falls apart on a narrow one, because
 * the ring is a fixed 24px and takes its width off the top before the text gets any.
 * Measured on /book/ at 390px: the cell is 95px, the ring plus gap eats 34 of it, and
 * the text column is left with 32px — so "8 spots left" set as
 *
 *     8
 *     spots
 *     left
 *
 * three lines, in every cell, in a column narrow enough that only three of the six
 * services were on screen at all.
 *
 * Stacking gives the text the full cell width instead of the leftovers. The ring keeps
 * its 24px above the label, where a fixed-size mark belongs.
 *
 * `white-space: nowrap` ON THE COUNT is the other half, and it is what makes the stack
 * worth doing. Without it the cell's minimum width becomes the longest WORD, so the
 * columns collapse further and the count wraps anyway. With it the minimum becomes
 * "12 spots left" — about 80px — every count sits on one line, and the six columns take
 * the width they need. `.ssr-pa-main` is already `overflow-x: auto`, so past that the
 * grid swipes sideways, which is what the component was built to do and is a better
 * phone pattern than six crushed columns that all fit and none of which can be read.
 *
 * 780px because that is where it starts to hurt: at 768 all six columns still fit
 * stacked with no sideways scroll at all — measured — and below it the swipe takes over
 * a column at a time.
 *
 * Applies to both pages that use the component. Their default `text-align` differs —
 * `center` on /book/, `start` on /availability/ — so centring is set here explicitly,
 * because a stacked mark and a left-aligned label under it is a worse layout than
 * either page had before.
 * ------------------------------------------------------------------------- */
@media (max-width: 780px) {
  .ssr-pa .slot {
    flex-direction: column;
    /* flex-start, not center: see the alignment note below — every slot on this grid
       reads down one left edge, stacked or not. */
    align-items: flex-start;
    gap: 2px;
  }
  .ssr-pa .slot .cnt { white-space: nowrap; }
}


/* ---------------------------------------------------------------------------
 * ONE ALIGNMENT FOR EVERY SLOT — another browser default, same family as the grey.
 *
 * Nick: "only the vb court rental label and subtext are aligned left. they all should
 * be." Correct, and the reason is the same thing that made the slots grey.
 *
 * NOTHING in the component sets `text-align` on a slot. It comes out of the element
 * the slot happens to be built from, and that varies by what the slot DOES:
 *
 *     Open Flow · VB Open Play · Sauna    <button class="slot is-pick">   center
 *     VB Court Rental                     <a class="slot s-available">    start
 *     Guided Flow · Hot Tub (Reserved)    <span class="slot s-reserved">  start
 *
 * `<button>` carries `text-align: center` from the user agent; an anchor and a span
 * inherit. So the alignment of a cell was decided by whether that service opens the
 * picker, links out, or is unavailable — three implementation details, none of which
 * the reader knows or should be able to see. Nick spotted it as "only VB court rental",
 * which is exactly what it looks like: one odd column, for no reason.
 *
 * Left for all of them, and left rather than centre because the column headers are
 * already `text-align: left` and so is the hour column down the side. That gives the
 * grid a single left edge per column instead of a mix, and it is the reading order —
 * you scan down a service, and a ragged left edge is what makes that hard.
 *
 * Set on `.slot` itself rather than on the button, so the value is declared once and
 * every variant inherits it, instead of three elements agreeing by accident.
 * ------------------------------------------------------------------------- */
.ssr-pa .slot,
.ssr-pa .slot .slab,
.ssr-pa .slot .cnt { text-align: left; }
