/* ============================================================
   SkyCity — Sky Tower page styles (skytower.css)
   Loaded globally via _Layout.cshtml, AFTER site.css.

   Page/feature-scoped block extracted from site.css so site.css
   holds only global foundations + shared primitives. These rules
   are inert on pages that don't render the Sky Tower markup.

   Contains: the Sky Tower split-hero (.sc-skytower*), the ticket /
   annual-pass price tables (.sc-pt-*), and the Explorer-app
   accordion (.sc-explorer-accordion*). Equal specificity to the
   original site.css rules but loaded later, so the small-screen
   overrides at the foot win exactly as before.

   Static file: plain @media only (never @@media).
   ============================================================ */

/* ── Split hero ──────────────────────────────────────────── */
.sc-skytower { position: relative; overflow: hidden; min-height: 480px; display: flex; align-items: center; }
.sc-skytower__bg { position: absolute; inset: 0; object-fit: cover; width: 100%; height: 100%; }
.sc-skytower__overlay { position: absolute; inset: 0; background: linear-gradient(to left, rgba(0,0,0,.7) 0%, rgba(0,0,0,.35) 55%, rgba(0,0,0,.08) 100%); }
.sc-skytower__content { position: relative; max-width: var(--sc-max-width); margin: 0 auto; padding: 4rem 1.5rem; width: 100%; display: flex; justify-content: flex-end; }
.sc-skytower__inner { max-width: 480px; text-align: right; }
.sc-skytower__activities { display: flex; gap: .625rem; flex-wrap: wrap; justify-content: flex-end; margin-bottom: 1.5rem; }
.sc-skytower__tag { font-size: .75rem; font-weight: 600; letter-spacing: .06em; color: rgba(255,255,255,.9); background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.25); border-radius: 50px; padding: .3rem .8rem; }

/* ============================================================
   SKY TOWER PRICE TABLES (.sc-pt-*)
   ============================================================ */

/* minmax raised 280px → 360px (2026-08-17) so the two cards stack at ~780px rather than ~630px.
   Derived, not guessed: at 280px they stacked at a measured ~630px viewport, so two columns
   plus the 24px gap were consuming (630 − ~46px container padding) = ~584px. To push the stack
   point to ~780px the pair must exceed (780 − 46) = 734px, i.e. min > 355. 🔴 The stack point is
   a function of THIS value, the gap AND the container padding — change any one and re-measure
   rather than assuming this number still holds. */
.sc-pt-prices { display: grid; grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)); gap: 24px; margin: 2rem 0; }
.sc-pt-card { background: #fff; border: 1px solid rgba(0,0,0,.08); border-radius: var(--sc-radius-card); padding: 22px 24px; display: flex; flex-direction: column; }

/* Primary (standard tickets) — solid gold. Plum is the ONLY text colour that
   survives here; see CLAUDE.md §2. Every child that was tuned for white needs
   an override below, including hairlines. */
.sc-pt-card--primary { background: var(--sc-gold); border-color: transparent; }
.sc-pt-card--primary .sc-pt-eyebrow { color: var(--sc-plum); opacity: .75; }
.sc-pt-card--primary .sc-pt-title { color: var(--sc-plum); }
.sc-pt-card--primary .sc-pt-rule { background: var(--sc-plum); }
.sc-pt-card--primary .sc-pt-table th { color: var(--sc-plum); border-bottom-color: rgba(68,11,34,.22); }
.sc-pt-card--primary .sc-pt-table td { color: var(--sc-plum); border-bottom-color: rgba(68,11,34,.22); }
.sc-pt-card--primary .sc-pt-note { color: rgba(68,11,34,.7); }

/* Secondary (annual pass) — stays white. Declared explicitly rather than left
   to the base rule so the pair reads as a deliberate contrast. */
.sc-pt-card--secondary { background: #fff; }

.sc-pt-cta { margin-top: auto; padding-top: 18px; }
.sc-pt-eyebrow { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--sc-plum); font-weight: 600; margin: 0 0 4px; }
.sc-pt-title { font-size: 1.125rem; font-weight: 700; color: var(--sc-text); margin: 0 0 4px; font-family: var(--sc-font); }
.sc-pt-rule { width: 42px; height: 3px; background: var(--sc-gold); border-radius: 2px; margin: 0 0 14px; }
.sc-pt-table { width: 100%; border-collapse: collapse; }
.sc-pt-table th { text-align: left; font-weight: 500; color: var(--sc-text); font-size: .9375rem; padding: 11px 0; border-bottom: 1px solid rgba(0,0,0,.07); vertical-align: top; }
.sc-pt-table td { text-align: right; font-weight: 700; color: var(--sc-plum); font-size: 1rem; padding: 11px 0; border-bottom: 1px solid rgba(0,0,0,.07); font-variant-numeric: tabular-nums; white-space: nowrap; }
.sc-pt-table tr:last-child th,
.sc-pt-table tr:last-child td { border-bottom: none; }
.sc-pt-note { display: block; font-size: .75rem; font-weight: 400; color: #6b6b6b; margin-top: 2px; }

/* Free pill — OUTLINED, and deliberately UNCONDITIONAL.
   It was rgba(220,183,65,.16) on #8a6a38: a translucent gold over an unknown
   surface, so it composited gold-on-gold and vanished the moment a card went
   gold. An opaque border + opaque text does not composite at all, so ONE rule
   is correct on white and on gold. Do not reintroduce a per-surface variant. */
.sc-pt-free { display: inline-block; background: transparent; border: 1px solid var(--sc-plum); color: var(--sc-plum); font-size: .6875rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; padding: 2px 9px; border-radius: 50px; }

/* ============================================================
   EXPLORER ACCORDION
   ============================================================ */

.sc-explorer-accordion__summary { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 1.1rem 1.4rem; cursor: pointer; list-style: none; user-select: none; border: 1px solid rgba(0,0,0,.12); border-radius: var(--sc-radius-card); transition: background .15s; }
.sc-explorer-accordion__summary::-webkit-details-marker { display: none; }
.sc-explorer-accordion__summary:hover { background: #f9f6f1; }
.sc-explorer-accordion__title { font-family: var(--sc-font); font-size: 1.15rem; font-weight: 600; color: var(--sc-text); }
.sc-explorer-accordion__icon { font-size: 1.5rem; color: var(--sc-gold); transition: transform .25s ease; flex-shrink: 0; }
.sc-explorer-accordion[open] .sc-explorer-accordion__icon { transform: rotate(180deg); }
.sc-explorer-accordion__body { padding: .75rem 0 0; }
@media (max-width: 600px) { .sc-explorer-accordion__body { padding: .5rem 0 0; } }

/* ── Small screens (was the .sc-skytower part of site.css's
   shared max-width:640px block) ──────────────────────────── */
@media (max-width: 640px) {
	.sc-skytower__inner { max-width: 100%; text-align: left; }
	.sc-skytower__activities { justify-content: flex-start; }
	.sc-skytower__overlay { background: linear-gradient(to top, rgba(0,0,0,.75) 0%, rgba(0,0,0,.2) 100%); }
}

/* ============================================================
   PRICE TABLES — INSULATION BLOCK REMOVED (2026-07-16)
   A `PRICE TABLES — INSULATE FROM GLOBAL CONTENT-TABLE STYLES`
   block lived here from 13 Jul. It re-asserted `.sc-pt-table`'s own
   look (margin, cell borders, padding, no zebra, no hover fill,
   `display:table` under 600px) purely to fight the global content-
   table rules in site.css, which at the time targeted bare
   `table`/`th`/`td` and leaked into these cards.

   Those site.css rules are now scoped to `table:not([class])`
   (2026-07-16) and cannot see `.sc-pt-table` at all — the class sits
   on the <table> element itself — so every declaration here became a
   no-op duplicating the real `.sc-pt-*` rules above (same 11px 0
   padding, same rgba(0,0,0,.07) bottom border, same last-row reset).
   Removed rather than left as dead code.

   DO NOT re-add it. If the price cards ever pick up borders, striping
   or a hover fill again, the cause is an UNSCOPED table rule in
   site.css — fix it there, not here. Patching this file was the wrong
   lever on 13 Jul and is why the leak recurred on 16 Jul. See
   CLAUDE.md §7, "Content-table rules MUST be scoped to
   `table:not([class])`".
   ============================================================ */

/* ============================================================
   SKY TOWER — School Holidays panel · cream intro · stat boxes
   (design refresh 2026-08, spec 06)
   ============================================================
   📌 RELOCATED FROM `site.css` ON 2026-08-21 (`tasks/chore-skytower-css-relocate.md`) — a pure
   cut-and-paste, 191 lines, byte-identical, verified as a no-op by computed styles before and
   after on `/sky-tower/`, the homepage and a restaurant. It lived in `site.css` only because
   spec 06 did not own this file. **This note used to say "recommend moving it"; it has moved.**
   🔴 THE MOVE WAS NOT RISK-FREE AND THE REASON IS WORTH KEEPING: `skytower.css` loads AFTER
   `site.css`, `whatson.css`, `news.css` and `explore.css`, so relocating a rule here RAISES its
   precedence at equal specificity. It was safe only because none of these class tokens exists in
   any of those four sheets, nor anywhere else in `site.css` — checked by extracting class TOKENS
   from both files rather than by substring, which is what distinguishes `.sc-skytower-intro`
   (site) from `.sc-skytower` (here): a shared prefix, not a collision.
   ⚠ If you ever move a block the other way, re-run that check first.

   Colours SAMPLED from `tower_schoolholidays.png` and `skytower_stats.png`, never chosen:
     panel ramp     #5A283C → #1E030E  ≈ --sc-grad-plum-stops, rotated to 90deg
     heading        #EDDBA0 -> --sc-gold-40   10.80:1 on the ramp's lightest stop
     subtitle       #F8F4E8  = --sc-cream      12.67:1
     button fill    #EDDBA0 -> --sc-gold-40
     button label   #1E020D -> --sc-plum       12.36:1 on the fill
     stat box fill  #ECDBA4 -> --sc-gold-40
     stat value     #440B22  = --sc-plum       12.36:1
     stat label     #693C4E  = --sc-plum-80     6.90:1
     intro surface  #F8F4E8  = --sc-cream
   Every one maps onto an existing token. Nothing new was added to :root. */

/* ── Part B: the intro sits on cream ─────────────────────────────────────────── */
.sc-skytower-intro { background: var(--sc-cream); }

/* 🔴 `.sc-pt-card` IS `background: #fff`, AND WHITE ON CREAM IS 1.10:1 — the card's EDGE
   disappears the moment the section behind it stops being white. Its 1px rgba(0,0,0,.08)
   border is not enough to hold it. The text inside is unaffected (12.63:1) which is exactly
   why an audit that only measures text would pass this and ship an invisible card.
   ⚠ The fix is specificity, NOT file order: `skytower.css` loads AFTER `site.css`, so a
   (0,1,0) rule here would lose. `.sc-skytower-intro .sc-pt-card` is (0,2,0) and wins from
   either file — which also means moving this block to `skytower.css` later changes nothing.
   ⚠ `--primary` is EXCLUDED: it is a gold card with `border-color: transparent` on purpose,
   and giving it a plum hairline would be a visible regression on a card that was already fine. */
.sc-skytower-intro .sc-pt-card:not(.sc-pt-card--primary) { border-color: rgba(68,11,34,.16); }

/* ── Part A: the School Holidays panel ───────────────────────────────────────── */
.sc-sh { padding: 3rem 0; }

/* The ramp is CONSUMED and only the ANGLE is new — which is the sanctioned pattern, stated at
   the token itself and already precedented by `.sc-surface--grad-diag` (135deg). The comp's
   panel is flat vertically and sweeps left→right, so 90deg. **No stop list is re-declared:
   #52152F / #3A0C1F / #1C0309 each appear exactly once in this file, in :root.** */
.sc-sh__panel {
	position: relative;
	overflow: hidden;
	border-radius: 14px;
	background: linear-gradient(90deg, var(--sc-grad-plum-stops));
	isolation: isolate;
}

/* 🔴 A MASK ON THE IMAGE ALONE WAS NOT ENOUGH, AND THE FIRST BUILD SHIPPED THE BUG THE SPEC
   WARNED ABOUT. Masking only the photo fades it toward the LEFT — but the heading is CENTRED on
   the panel, so its right-hand tail reached into the zone where the photo was still fully opaque.
   Rendered against a deliberately hostile test image (near-white sky at the right edge), the word
   "Programmes" became gold-40 on near-white and was unreadable. **Caught by looking at it; the
   computed styles were all correct.**
   The fix is BOTH layers, which is what the comp actually does:
     .sc-sh__bg      — the photo, masked so it fades out toward the LEFT
     .sc-sh__panel::after — the plum ramp AGAIN, over the photo, masked so it fades out toward the
                       RIGHT. Fully opaque across the left 66%, gone by 96%.
   So text always sits on plum, whatever photo an editor picks, and the photo still reads in the
   right quarter exactly as the comp shows.
   ⚠ THE SCRIM CONSUMES `var(--sc-grad-plum-stops)` — it is the same ramp painted twice, NOT a
   second stop list. #52152F / #3A0C1F / #1C0309 still appear exactly once each in this file.
   ⚠ `mask-image` carries the -webkit- prefix for older Safari. With neither supported the scrim
   would be fully opaque and the photo simply would not show — degrading to the no-image panel,
   which is the safe direction. */
.sc-sh__bg {
	position: absolute;
	inset: 0 0 0 auto;
	width: 58%;
	z-index: 0;
	-webkit-mask-image: linear-gradient(270deg, #000 55%, transparent 100%);
	mask-image: linear-gradient(270deg, #000 55%, transparent 100%);
}
.sc-sh__bg img { width: 100%; height: 100%; object-fit: cover; display: block; }

.sc-sh__panel::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	background: linear-gradient(90deg, var(--sc-grad-plum-stops));
	-webkit-mask-image: linear-gradient(90deg, #000 0%, #000 66%, transparent 96%);
	mask-image: linear-gradient(90deg, #000 0%, #000 66%, transparent 96%);
}

.sc-sh__inner {
	position: relative;
	z-index: 2;
	text-align: center;
	padding: clamp(2.25rem, 5vw, 3.5rem) clamp(1.25rem, 4vw, 3rem);
	max-width: 54rem;
	margin: 0 auto;
}

.sc-sh__heading {
	font-family: var(--sc-font-display);
	font-weight: 800;
	font-size: clamp(1.75rem, 4.2vw, 3rem);
	line-height: 1.1;
	color: var(--sc-gold-40);
	margin: 0;
}
.sc-sh__lead { color: var(--sc-cream); font-size: 1rem; line-height: 1.6; margin: .875rem auto 0; max-width: 46rem; }

/* ⚠ NOT `.sc-btn--gold`. The comp's button is a PALE fill with a PLUM label (12.36:1); the brand
   primary is a saturated gold fill with a WHITE label, which is the documented 1.93:1 §2
   exception. Reusing `.sc-btn--gold` here would have imported that exception onto a dark panel
   where it is not required and not wanted. The §2 exception is untouched — this is a sibling. */
.sc-sh__cta {
	display: inline-flex;
	align-items: center;
	gap: .875rem;
	margin-top: 1.75rem;
	padding: .75rem .875rem .75rem 1.75rem;
	border: 2px solid transparent;
	border-radius: var(--sc-radius-btn);
	background: var(--sc-gold-40);
	color: var(--sc-plum);
	font-family: var(--sc-font);
	font-size: .875rem;
	font-weight: 700;
	letter-spacing: .107em;
	text-transform: uppercase;
	cursor: pointer;
	transition: background .2s, color .2s;
}
.sc-sh__cta:hover { background: var(--sc-gold-60); }
.sc-sh__cta:focus-visible { outline: 2px solid var(--sc-cream); outline-offset: 3px; }

/* The stack comes from the FIRST FOUR of `schoolHolidaysGallery` — no property was added for it.
   Negative margin overlaps them; the ring is the button's own fill so they read as cut-outs. */
.sc-sh__stack { display: inline-flex; flex-shrink: 0; }
.sc-sh__stack img {
	width: 34px;
	height: 34px;
	border-radius: 50%;
	object-fit: cover;
	display: block;
	box-shadow: 0 0 0 2px var(--sc-gold-40);
}
.sc-sh__stack img + img { margin-left: -12px; }

@media (max-width: 640px) {
	.sc-sh__cta { padding-left: 1.25rem; letter-spacing: .06em; }
	.sc-sh__stack img { width: 28px; height: 28px; }
	.sc-sh__stack img + img { margin-left: -10px; }
	.sc-sh__bg { width: 100%; opacity: .45; }
}

/* ── Part C: the stat boxes ──────────────────────────────────────────────────── */
.sc-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.25rem; margin-top: 2.5rem; }
.sc-stat {
	background: var(--sc-gold-40);
	border-radius: 10px;
	padding: 1.75rem 1.25rem;
	text-align: center;
}
/* ⚠ The suffix is a SUPERSCRIPT, and `vertical-align: super` alone would push the line box open
   and make the boxes different heights. `font-size` + a negative `top` on a relative inline box
   raises it without touching line height — the same reason `<sup>` is avoided here. */
.sc-stat__value {
	font-family: var(--sc-font-display);
	font-weight: 800;
	font-size: clamp(2rem, 3.4vw, 2.75rem);
	line-height: 1;
	color: var(--sc-plum);
	display: block;
}
.sc-stat__suffix {
	font-size: .45em;
	font-weight: 800;
	position: relative;
	top: -.72em;
	letter-spacing: .02em;
}
.sc-stat__label {
	font-size: .8125rem;
	font-weight: 600;
	line-height: 1.45;
	color: var(--sc-plum-80);
	margin: .75rem 0 0;
}

@media (max-width: 900px) { .sc-stats { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .sc-stats { grid-template-columns: 1fr; } }
