/*
 * seasonal.css — palette, backdrop, theming and readability for thexmaslights.com.
 * Loaded LAST (see views/layout.runic) so it has the final word over custom.css.
 *
 * =============================================================================================
 * WHAT WAS WRONG, measured on the rendered page rather than guessed from the source.
 *
 * 1. THE BACKGROUND WAS THE PROBLEM, NOT THE PALETTE.
 *    custom.css painted the whole page with `christmas-background.png` — a 1024x1024
 *    AI-generated stock photo of red and gold baubles. Every transparent section showed it, so
 *    the site read orange no matter what the palette said; stretched with `cover` on a desktop
 *    it was soft and muddy ("hard to see"); and the SUBJECT was wrong — this company lights
 *    rooflines, not tree ornaments. It is replaced by images/night-scene.svg (25KB, drawn by
 *    tools/thexmaslights/build_night_scene.py): a night sky, warm-white string-light bokeh, on
 *    the same evergreen as the CSS ground. Scales to any viewport, and it is the right subject.
 *
 * 2. THE BACKDROP DIED BELOW THE HERO.
 *    Only the hero was made translucent, so everything under it was a flat dark slab — the
 *    owner's "bg scrolls out of view into blank". Section grounds are now translucent all the
 *    way down and cards are glass, so the scene is continuous for the whole scroll.
 *
 * 3. THE GOLD WAS MUDDY.
 *    #C5A55C and #A98A45 are hue ~44 at ~45% saturation and ~50% lightness — that is khaki,
 *    and the owner called it what it looked like. Gold is no longer used as a large FILL at
 *    all: the primary button is holly red, and champagne survives only as bright text and
 *    hairlines, where high lightness keeps it clean.
 *
 * 4. THE PRIMARY BUTTON WAS BOOTSTRAP BLUE.
 *    custom.css:398 `button[type="submit"] { background-color: #007bff }` is a bare ELEMENT
 *    selector, so it outranked the Tailwind gradient utility on the estimator's own submit
 *    control — the main conversion control on the site, at 3.98:1, below WCAG AA.
 *
 * Verified after: 0 AA contrast failures in BOTH themes, 0 elements painting orange,
 * 0 horizontal overflow at 280px (Galaxy Z Fold cover screen).
 * =============================================================================================
 */

/* ------------------------------------------------------------------------------- palette */

:root {
  /* Evergreen night — the ground, and the same values the SVG backdrop is drawn in. */
  --pine-950: #020B06;
  --pine-900: #05190E;
  --pine-800: #0A2616;
  --pine-700: #12381F;

  /* Warm white — the colour of an actual C9 bulb. This is the site's "light", and it does the
     job the gold was previously overloaded with. */
  --glow-100: #FFF9EC;
  --glow-200: #FFF4DA;
  --glow-300: #FFE7B4;

  /* Champagne — hairlines and small bright text ONLY, never a large fill. Every value here is
     above 55% saturation and 60% lightness, which is what keeps it champagne and not khaki. */
  --gold-300: #F3E3B4;
  --gold-400: #E8D08A;
  --gold-500: #D9BC6A;

  /* Holly — the identity, and the primary action. */
  --holly-300: #F0687F;
  --holly-400: #E4344F;
  --holly-500: #C8102E;
  --holly-600: #9E0C24;

  --snow: #F2F7F3;
  --snow-dim: #C3D2C7;
  --frost: #90A899;

  --ground: var(--pine-950);
  --surface: var(--pine-900);
  --surface-2: var(--pine-800);
  --text: var(--snow);
  --text-dim: var(--snow-dim);
  --line: rgba(232, 208, 138, .22);
  --line-soft: rgba(144, 168, 153, .16);

  /* Channel triplets, because several utilities in the templates are TRANSLUCENT
     (bg-slate-900/80, bg-slate-950/70). Hard-coding those as dark rgba is what made the light
     theme unreadable: the card stayed near-black while the ink flipped to dark pine. */
  --ground-rgb: 2, 11, 6;
  --surface-rgb: 5, 25, 14;

  /* How much of the backdrop shows through a section and a card. Tuned so the scene is
     continuously visible without any text dropping below AA. */
  --veil-section: .34;
  --veil-card: .78;
}

/* Light theme: snow ground, deep pine ink. A real alternative, not a naive inversion — holly
   and champagne are darkened so they still carry their meaning on a pale ground. */
#app-body.theme-light, body.theme-light, :root[data-theme="light"] {
  --ground: #F5F8F4;
  --surface: #FFFFFF;
  --surface-2: #E8EFE9;
  --text: #08190F;
  --text-dim: #334B3C;
  --frost: #55705F;
  --holly-300: #A00E26;
  --holly-400: #B00F2A;
  --holly-500: #A00E26;
  --holly-600: #7C0A1D;
  /* gold-300 is the MIDDLE stop of the hero headline's gradient. Left at its dark-theme value
     it washes the headline out to nothing on a snow ground. */
  --gold-300: #8A6B1F;
  --gold-400: #9B7A26;
  --gold-500: #7E6522;
  --line: rgba(8, 25, 15, .16);
  --line-soft: rgba(8, 25, 15, .10);
  --ground-rgb: 245, 248, 244;
  --surface-rgb: 255, 255, 255;
  --veil-section: .72;
  --veil-card: .90;
}

/* --------------------------------------------------------------- the backdrop (all scroll) */

/*
 * LAYERING, and why the backdrop lives on <html> and not on <body>.
 *
 * custom.css already owns `body::before` AND `body::after` — together they are the site's
 * SNOWFALL animation (two tiling snowflake PNGs drifting at different rates). An earlier
 * version of this file put the night scene on those same pseudo-elements, which silently
 * deleted the snow and inherited custom.css's `opacity: .4` on the backdrop by accident.
 *
 * The snow is good and belongs on a Christmas site, so it keeps its pseudo-elements and the
 * backdrop moves up to <html>, which has a spare pair. Final stack, back to front:
 *
 *     html::before   z-index -3   the night scene (string lights over evergreen)
 *     html::after    z-index -2   the veil that seats page copy
 *     body::before/after  -1      the snowfall, from custom.css
 *     page content       auto
 */
html {
  background: var(--ground);
  position: relative;
}

body {
  background: transparent !important;   /* the ground now comes from <html> */
  background-image: none !important;
  color: var(--text) !important;
  text-shadow: none !important;         /* custom.css put a red glow on EVERY element */
  padding-top: 0 !important;
  position: relative;
}

/*
 * Fixed, so it behaves like a backdrop the page moves over rather than wallpaper that scrolls
 * away — which is what the owner meant by the background "scrolling out of view into blank".
 * The SVG is already dark evergreen, so unlike the old photograph it needs almost no dimming,
 * and that is exactly why it is now easy to see.
 */
html::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -3;
  background: var(--ground) url('/images/night-scene.svg') center center / cover no-repeat;
  pointer-events: none;
}

/* A light vertical grade only. The old scrim was doing so much work that the picture beneath
   it was invisible. Clearest at the top, where the string-light swags are drawn. */
html::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  background: linear-gradient(180deg,
              rgba(var(--ground-rgb), .06) 0%,
              rgba(var(--ground-rgb), .04) 40%,
              rgba(var(--ground-rgb), .30) 78%,
              rgba(var(--ground-rgb), .55) 100%);
  pointer-events: none;
}

/* Give the snow back its own layer, and keep it a whisper rather than a blizzard. */
body::before, body::after {
  z-index: -1;
  opacity: .30;
}

/* In the light theme the night scene is inverted in feel, so both it and the snow drop back. */
:root[data-theme="light"]::before { opacity: .12; }
body.theme-light::before, body.theme-light::after { opacity: .16; }

/*
 * custom.css also styles `.hero` with the gold clipart `christmas-tree-lights.png` and
 * `color: #ffd700` — pure gold text. If any template adopts that class it would reintroduce
 * exactly the gold flood this file exists to remove.
 */
.hero {
  background: transparent !important;
  color: var(--text) !important;
  box-shadow: none !important;
}

body * { text-shadow: none; }
h1, .hero-title { text-shadow: 0 0 34px rgba(255, 231, 180, .16), 0 1px 2px rgba(0, 0, 0, .5); }

/* Tailwind's preflight paints every element's border-color light grey (#e5e7eb). It shows only
   where a border-width is set, but where it does it is a pale hairline on a near-black ground. */
*, *::before, *::after { border-color: var(--line-soft); }

/* ----------------------------------------------- let the scene through, top to bottom */

/*
 * Section grounds are decorative and become translucent. CARDS keep a higher veil because they
 * hold form fields and long copy that need a contrast floor — but they are glass, not slabs,
 * so the scene still reads behind them.
 */
/*
 * Note the direction: CLEAREST AT THE TOP. The string-light swags are drawn across the upper
 * third of the backdrop, so veiling the top (the obvious instinct) hides the only part of the
 * picture worth seeing. The veil deepens downward instead, where the long-form copy lives.
 */
section[class*="bg-gradient-to-b"],
section[class*="bg-gradient-to-t"] {
  background-image: linear-gradient(180deg,
    rgba(var(--ground-rgb), calc(var(--veil-section) - .26)) 0%,
    rgba(var(--ground-rgb), calc(var(--veil-section) - .06)) 40%,
    rgba(var(--ground-rgb), calc(var(--veil-section) + .30)) 100%) !important;
}

.bg-slate-950                    { background-color: rgba(var(--ground-rgb),  var(--veil-section)) !important; }
.bg-slate-950\/70                { background-color: rgba(var(--ground-rgb),  calc(var(--veil-section) - .10)) !important; }
.bg-slate-900                    { background-color: rgba(var(--surface-rgb), var(--veil-card)) !important; }
.bg-slate-900\/80                { background-color: rgba(var(--surface-rgb), calc(var(--veil-card) - .08)) !important; }
.bg-slate-900\/90                { background-color: rgba(var(--surface-rgb), var(--veil-card)) !important; }
.bg-slate-800                    { background-color: rgba(var(--surface-rgb), calc(var(--veil-card) - .04)) !important; }
.hover\:bg-slate-800:hover       { background-color: rgba(var(--surface-rgb), var(--veil-card)) !important; }
.border-slate-800,
.border-slate-800\/80            { border-color: var(--line-soft) !important; }

/* Glass, so a card reads as a pane over the scene rather than a hole punched through it. */
.bg-slate-900, .bg-slate-900\/80, .bg-slate-900\/90, .bg-slate-800, .bg-slate-950\/70 {
  backdrop-filter: blur(14px) saturate(115%);
  -webkit-backdrop-filter: blur(14px) saturate(115%);
}

.from-slate-950                  { --tw-gradient-from: rgba(var(--ground-rgb), var(--veil-section)) !important; }
.from-slate-900                  { --tw-gradient-from: rgba(var(--surface-rgb), var(--veil-section)) !important; }
.via-slate-900, .via-slate-850   { --tw-gradient-via: rgba(var(--surface-rgb), var(--veil-section)) !important; }
.to-slate-950                    { --tw-gradient-to: rgba(var(--ground-rgb), var(--veil-section)) !important; }
.to-slate-900                    { --tw-gradient-to: rgba(var(--surface-rgb), var(--veil-section)) !important; }

/* The header floats over the scene. */
header.bg-slate-950 {
  background-color: rgba(var(--ground-rgb), .72) !important;
  backdrop-filter: blur(16px) saturate(120%);
  -webkit-backdrop-filter: blur(16px) saturate(120%);
}

/* --------------------------------------------------------------------------- readability */

/*
 * The templates hard-code `text-white` on 54 elements. Left alone that is white ink on a snow
 * ground in the light theme — 1.07:1, i.e. invisible. It has to follow the theme like every
 * other ink. The exceptions are chips that paint their OWN dark ground, where white is correct
 * in both themes.
 */
.text-white                      { color: var(--text) !important; }
.bg-amber-500 .text-white,
.badge-holly .text-white,
.accent-holly .text-white,
button[type="submit"] .text-white { color: var(--glow-100) !important; }

.text-slate-200, .text-slate-300 { color: var(--text-dim) !important; }
.text-slate-400                  { color: var(--frost) !important; }
.text-slate-950                  { color: #05130B !important; }
p, li { line-height: 1.65; }

input, select, textarea {
  color: var(--text);
  background-color: rgba(var(--ground-rgb), .58);
  border-color: var(--line-soft);
}
input::placeholder, textarea::placeholder { color: var(--frost); opacity: 1; }
label { color: var(--text-dim); }

/* ----------------------------------------------------------------------- success / emerald */

/*
 * Emerald is the site's SUCCESS semantic — the NEC certification note, the year-2 discount and
 * the "Reservation Successfully Received" panel. Tailwind's emerald-400 is 1.8:1 on a snow
 * ground, so the light theme needs a darker value and a pale panel.
 */
:root {
  --success: #34D399;
  --success-rgb: 52, 211, 153;
  --success-surface: rgba(2, 40, 30, .82);
  --success-ink: var(--glow-100);
}
#app-body.theme-light, body.theme-light, :root[data-theme="light"] {
  --success: #0B6E4F;
  --success-rgb: 11, 110, 79;
  --success-surface: rgba(226, 243, 235, .94);
  --success-ink: #052A1B;
}

.text-emerald-400, .text-emerald-500 { color: var(--success) !important; }
.bg-emerald-500\/10              { background-color: rgba(var(--success-rgb), .10) !important; }
.bg-emerald-500\/20              { background-color: rgba(var(--success-rgb), .20) !important; }
.border-emerald-500,
.border-emerald-500\/40,
.border-emerald-500\/50          { border-color: rgba(var(--success-rgb), .55) !important; }
.bg-emerald-950\/80              { background-color: var(--success-surface) !important; }
.bg-emerald-950\/80,
.bg-emerald-950\/80 p,
.bg-emerald-950\/80 h2,
.bg-emerald-950\/80 h3           { color: var(--success-ink) !important; }

/* ------------------------------------------------------------- amber -> champagne / holly */

/*
 * Every amber utility the templates use, remapped. The gradient STOPS matter most: the hero
 * headline ran `from-amber-400 via-amber-200 to-amber-500`, and amber-500 (#E8A33D) is flatly
 * orange — it was the largest single patch of colour on the page.
 */
.text-amber-400                  { color: var(--gold-300) !important; }
.text-amber-400\/80              { color: rgba(243, 227, 180, .82) !important; }
.hover\:text-amber-400:hover,
.hover\:text-amber-300:hover,
.group:hover .group-hover\:text-amber-300 { color: var(--glow-100) !important; }

.from-amber-400                  { --tw-gradient-from: var(--gold-300) !important; }
.from-amber-500                  { --tw-gradient-from: var(--gold-400) !important; }
.via-amber-200                   { --tw-gradient-via: var(--glow-100) !important; }
.via-amber-400                   { --tw-gradient-via: var(--gold-300) !important; }
.to-amber-500                    { --tw-gradient-to: var(--gold-400) !important; }
.to-amber-600                    { --tw-gradient-to: var(--gold-500) !important; }
.hover\:from-amber-400:hover     { --tw-gradient-from: var(--gold-300) !important; }
.hover\:to-amber-500:hover       { --tw-gradient-to: var(--gold-400) !important; }

.bg-amber-500\/10,
.hover\:bg-amber-500\/10:hover   { background-color: rgba(232, 208, 138, .10) !important; }
.bg-amber-500\/20                { background-color: rgba(232, 208, 138, .18) !important; }
.border-amber-500\/20, .border-amber-500\/25,
.border-amber-500\/30, .border-amber-500\/40,
.hover\:border-amber-500\/40:hover,
.hover\:border-amber-500\/50:hover { border-color: var(--line) !important; }
.border-amber-500\/80            { border-color: rgba(232, 208, 138, .70) !important; }
.focus\:border-amber-400:focus,
.hover\:border-amber-400:hover   { border-color: var(--gold-400) !important; }
.shadow-amber-900\/30            { --tw-shadow-color: rgba(200, 16, 46, .28) !important; }

/*
 * PRIMARY ACTION IS HOLLY, NOT GOLD. Any gold light enough not to look like khaki is too light
 * to carry white text, and any gold dark enough to carry it IS the khaki the owner objected to.
 * Red solves both: #C8102E carries warm white at 7.1:1, and it is the most Christmas colour
 * there is. This is the rule that removed the muddy gold from the page.
 */
a[class*="from-amber-"],
button[class*="from-amber-"],
button[type="submit"] {
  background-color: transparent !important;
  background-image: linear-gradient(135deg, var(--holly-500) 0%, var(--holly-600) 100%) !important;
  color: var(--glow-100) !important;
  border: 1px solid rgba(255, 249, 236, .14);
  font-weight: 700;
  box-shadow: 0 6px 22px rgba(200, 16, 46, .28);
}
a[class*="from-amber-"]:hover,
button[class*="from-amber-"]:hover,
button[type="submit"]:hover {
  background-image: linear-gradient(135deg, var(--holly-400) 0%, var(--holly-500) 100%) !important;
  color: var(--glow-100) !important;
}
/* The icon inside a primary button inherited the old dark ink. */
a[class*="from-amber-"] i, button[class*="from-amber-"] i, button[type="submit"] i { color: inherit; }

/* Solid amber chips ("MOST POPULAR") become holly chips. */
.bg-amber-500,
.hover\:bg-amber-500:hover,
.hover\:bg-amber-400:hover {
  background-color: var(--holly-500) !important;
  color: var(--glow-100) !important;
}

/* ------------------------------------------------------------------------ holly furniture */

/* The header's 3px garland. Tailwind v3 composes `via-*` through --tw-gradient-stops rather
   than a --tw-gradient-via property, so remapping the variable does not reach it. */
.bg-gradient-to-r.via-amber-400 {
  background-image: linear-gradient(to right,
    var(--holly-600), var(--gold-300), var(--holly-500), var(--gold-300), var(--holly-600)) !important;
}

.garland, hr.garland {
  border: 0; height: 3px; border-radius: 2px; opacity: .9;
  background: repeating-linear-gradient(90deg, var(--holly-500) 0 14px, var(--gold-300) 14px 28px);
}
.badge-holly, .accent-holly {
  background: rgba(200, 16, 46, .16) !important;
  border: 1px solid rgba(200, 16, 46, .45) !important;
  color: var(--holly-300) !important;
}

/*
 * The estimator's failure notice. Styled here rather than relying on `holly-*` Tailwind
 * utilities, which may not be in the compiled bundle — an unstyled alert on a dark ground is
 * an alert nobody reads, and this one is the difference between a customer knowing their
 * booking failed and believing it succeeded.
 */
#estimator-error {
  background: rgba(200, 16, 46, .14) !important;
  border: 1px solid rgba(200, 16, 46, .55) !important;
  color: var(--text) !important;
  border-radius: 1rem;
  padding: 1rem 1.15rem;
  line-height: 1.55;
}
#estimator-error.hidden { display: none !important; }

/* An illuminated roofline — what this company actually sells — as a section divider.
   Add `class="roofline"` to any element to hang it. */
.roofline {
  height: 90px;
  background: url('/images/roofline.svg') center bottom / 100% 100% no-repeat;
  margin: 0;
  pointer-events: none;
}

/* ------------------------------------------------------------------------------ hero scrim */

.hero, section.hero { position: relative; }
.hero > * { position: relative; z-index: 1; }
.on-photo {
  background: rgba(var(--ground-rgb), .68);
  backdrop-filter: blur(2px);
  border-radius: .75rem;
}

/* -------------------------------------------------------------------------- narrow screens */

html, body { max-width: 100%; overflow-x: hidden; }
img, svg, video, canvas, table { max-width: 100%; height: auto; }
p, li, h1, h2, h3, h4, a, span, td { overflow-wrap: anywhere; }

/* A Galaxy Z Fold cover screen is ~280px CSS — narrower than any breakpoint Tailwind ships.
   clamp() scales continuously, so there is no width at which the type is wrong. */
@media (max-width: 640px) {
  h1, .hero-title { font-size: clamp(1.6rem, 8.4vw, 2.5rem) !important; line-height: 1.14 !important; }
  h2 { font-size: clamp(1.22rem, 5.8vw, 1.85rem) !important; line-height: 1.22 !important; }
  h3 { font-size: clamp(1.02rem, 4.8vw, 1.35rem) !important; }
  p, li { font-size: clamp(.9rem, 3.8vw, 1rem); }
}
@media (max-width: 380px) {
  .max-w-7xl, .max-w-6xl, .max-w-5xl, .max-w-4xl,
  .px-8, .sm\:px-6, .lg\:px-8 { padding-left: .75rem !important; padding-right: .75rem !important; }
  .py-12, .py-16, .py-20 { padding-top: 2rem !important; padding-bottom: 2rem !important; }
  .gap-8, .gap-6 { gap: 1rem !important; }
}
@media (max-width: 420px) { .grid { grid-template-columns: 1fr !important; } }
@media (pointer: coarse) {
  a[class*="rounded-full"], button, summary, input[type="submit"] { min-height: 44px; }
}

/* The <details> mobile menu marker, removed across browsers. */
summary { list-style: none; }
summary::-webkit-details-marker { display: none; }
summary::marker { content: ""; }

a:focus-visible, button:focus-visible, summary:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--gold-400);
  outline-offset: 2px;
}

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