/* ==========================================================================
   Digital Shields — scene backdrop: the protection horizon
   Behind the website heroes (.hero--scene), other page heads (.scene-host),
   the portal header band (.scene--home, .scene--band) and the schools
   sign-in screen (.scene--auth).

   The idea is a shield's reach. Centred on the thing the page is offering
   (the demo card, the sign-in card) sit faint concentric "protection
   radius" rings; behind it a crisp gold horizon (the edge of a very large
   circle) rises from the lower left and crests to the upper right, lit on
   the inside. A restrained cool wash sits in the opposite corner and a fine
   dot grid fades out before it reaches the copy, so headlines stand on a
   clean, calm ground. Pure CSS gradients and one SVG: no images, no blur.

   Markup (views/partials/scene.html, /app/components/scene.js):
     <div class="scene" aria-hidden="true">
       <i class="scene__wash"></i><i class="scene__grid"></i><i class="scene__arc"></i>
       <i class="scene__rings"><svg>…concentric circles…</svg></i>
     </div>

   Geometry: everything is placed from one anchor point, --ax/--ay (with
   the anchor's size in --aw/--ah). /ds/scene.js measures the anchor (the
   hero's demo card, the sign-in card) and sets them on the scene; without
   one the variant's defaults below apply.
   Motion: /ds/scene.js drifts the layers at different rates as the page
   scrolls and, on desktop heroes, tilts them a little with the pointer
   (transform only). Under prefers-reduced-motion nothing moves.
   Decorative only: aria-hidden, no pointer events, hidden in print.
   ========================================================================== */

/* ---------- Theme ----------
   Light: luminous means lighter than the Mist ground, so the glows mix
   towards white and a clean gold, never towards grey. Anything that can sit
   behind text (the halo, the wash) is kept light enough that --text-3 stays
   AA on it; only the thin rim line is full gold. */
:root {
  --sc-line: var(--gold-500);
  --sc-line-hi: #FFE27A;
  --sc-halo: rgba(255, 236, 176, .45);   /* outside the rim: warm light */
  --sc-rim: rgba(255, 232, 150, .3);      /* just inside the rim */
  --sc-inner: rgba(255, 255, 255, .78);   /* the lit side, fading inwards */
  --sc-body: rgba(255, 255, 255, .30);    /* the far side of the horizon */
  --sc-ring: #3F5E80;                     /* navy-500, used at low opacity */
  --sc-ring-o: .26;
  --sc-ring-gold: #C99A00;
  --sc-wash-core: rgba(255, 255, 255, .8);
  --sc-wash: rgba(77, 148, 255, .12);
  --sc-wash-2: rgba(19, 128, 108, .06);
  --sc-dot: rgba(27, 51, 80, .16);
}
/* Dark: designed for navy, not inverted. The rim glows, the lit side is a
   faint gold-to-blue light, the rings are fine white lines. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --sc-line: #FFD43B;
    --sc-line-hi: #FFE88F;
    --sc-halo: rgba(245, 197, 24, .26);
    --sc-rim: rgba(245, 197, 24, .16);
    --sc-inner: rgba(91, 147, 245, .10);
    --sc-body: rgba(120, 160, 230, .035);
    --sc-ring: #FFFFFF;
    --sc-ring-o: .10;
    --sc-ring-gold: #F5C518;
    --sc-wash-core: rgba(91, 147, 245, .12);
    --sc-wash: rgba(91, 147, 245, .1);
    --sc-wash-2: rgba(43, 181, 150, .06);
    --sc-dot: rgba(255, 255, 255, .075);
  }
}
:root[data-theme="dark"] {
  --sc-line: #FFD43B;
  --sc-line-hi: #FFE88F;
  --sc-halo: rgba(245, 197, 24, .26);
  --sc-rim: rgba(245, 197, 24, .16);
  --sc-inner: rgba(91, 147, 245, .10);
  --sc-body: rgba(120, 160, 230, .035);
  --sc-ring: #FFFFFF;
  --sc-ring-o: .10;
  --sc-ring-gold: #F5C518;
  --sc-wash-core: rgba(91, 147, 245, .12);
  --sc-wash: rgba(91, 147, 245, .1);
  --sc-wash-2: rgba(43, 181, 150, .06);
  --sc-dot: rgba(255, 255, 255, .075);
}

/* ---------- Scene ---------- */
.scene {
  /* the anchor: centre and size (set by scene.js when there is one) */
  --ax: 76%; --ay: 52%; --aw: 520px; --ah: 640px;
  /* the horizon: a circle of radius --R whose centre sits below and to the
     right of the anchor, so its edge rises behind it from the lower left */
  --R: clamp(760px, 92vw, 1320px);
  --G: 90px; /* room outside the rim for the halo */
  --arc-x: calc(var(--ax) + var(--R) * .55);
  --arc-y: calc(var(--ay) + var(--R) * .85);
  /* the rings, centred on the anchor */
  --ring-x: var(--ax); --ring-y: var(--ay);
  --ring-s: clamp(900px, 128vw, 1800px);
  position: absolute; inset: 0; overflow: hidden; overflow: clip;
  pointer-events: none; user-select: none; z-index: -1;
  /* fade in under the site header and out into whatever sits below */
  -webkit-mask-image: linear-gradient(transparent, #000 88px, #000 calc(100% - 120px), transparent);
  mask-image: linear-gradient(transparent, #000 88px, #000 calc(100% - 120px), transparent);
}
.scene > i { position: absolute; display: block; translate: -50% -50%; }
.scene.is-live > i { will-change: transform; }

/* the cool wash, centred off the corner opposite the horizon so only its
   soft edge reaches the copy */
.scene__wash {
  left: var(--wash-x, -6%); top: var(--wash-y, -14%);
  width: min(1000px, 110vw); aspect-ratio: 1.3;
  background:
    radial-gradient(closest-side, var(--sc-wash), color-mix(in srgb, var(--sc-wash) 45%, transparent) 55%, transparent),
    radial-gradient(closest-side at 64% 70%, var(--sc-wash-2), transparent 80%),
    radial-gradient(closest-side, var(--sc-wash-core), transparent);
}

/* the dot grid: around the anchor, gone before it reaches the copy */
.scene__grid {
  left: 50%; top: 50%; width: 100%; height: 100%;
  background: radial-gradient(circle, var(--sc-dot) 1px, transparent 1.6px) 0 0 / 22px 22px;
  -webkit-mask-image: radial-gradient(calc(var(--aw) * .5 + 140px) calc(var(--ah) * .62 + 160px) at calc(var(--ax) + 40px) var(--ay), #000 30%, transparent);
  mask-image: radial-gradient(calc(var(--aw) * .5 + 140px) calc(var(--ah) * .62 + 160px) at calc(var(--ax) + 40px) var(--ay), #000 30%, transparent);
}

/* the horizon: a crisp gold rim with a halo outside and light inside.
   A conic mask fades the rim in from the lower left (where the copy is)
   and out again past the crest. */
.scene__arc {
  left: var(--arc-x); top: var(--arc-y);
  width: calc(2 * (var(--R) + var(--G))); aspect-ratio: 1;
  border-radius: 50%;
  background:
    radial-gradient(closest-side,
      transparent calc(100% - var(--G) - 2.5px),
      var(--sc-line) calc(100% - var(--G) - 1.25px),
      var(--sc-line-hi) calc(100% - var(--G) - .25px),
      var(--sc-line) calc(100% - var(--G) + .5px),
      var(--sc-halo) calc(100% - var(--G) + 1.75px),
      color-mix(in srgb, var(--sc-halo) 34%, transparent) calc(100% - var(--G) * .7),
      transparent 100%),
    radial-gradient(closest-side,
      var(--sc-body) calc(100% - var(--G) - 420px),
      var(--sc-inner) calc(100% - var(--G) - 90px),
      var(--sc-rim) calc(100% - var(--G) - 3px),
      transparent calc(100% - var(--G) - 1.5px));
  -webkit-mask-image: conic-gradient(from 268deg, transparent 0deg, #000 50deg, #000 112deg, transparent 150deg);
  mask-image: conic-gradient(from 268deg, transparent 0deg, #000 50deg, #000 112deg, transparent 150deg);
}

/* the protection radius: concentric rings, fading outwards */
.scene__rings {
  left: var(--ring-x); top: var(--ring-y);
  width: var(--ring-s); aspect-ratio: 1;
  /* fade outwards, and sooner on the left, towards the copy */
  -webkit-mask-image: radial-gradient(46% 50% at var(--ring-mx, 62%) 50%, #000 34%, transparent 88%);
  mask-image: radial-gradient(46% 50% at var(--ring-mx, 62%) 50%, #000 34%, transparent 88%);
}
.scene__rings svg { display: block; width: 100%; height: 100%; overflow: visible; }
.scene__rings circle { fill: none; stroke: var(--sc-ring); stroke-width: 1; vector-effect: non-scaling-stroke; opacity: var(--sc-ring-o); }
.scene__rings .r2 { opacity: calc(var(--sc-ring-o) * .85); }
.scene__rings .r3 { opacity: calc(var(--sc-ring-o) * .7); }
.scene__rings .r4 { opacity: calc(var(--sc-ring-o) * .55); }
.scene__rings .r5 { opacity: calc(var(--sc-ring-o) * .4); }
/* one ring picked out in gold, broken into segments like a dial */
.scene__rings .rg { stroke: var(--sc-ring-gold); stroke-width: 1.5; stroke-dasharray: 2 6; opacity: .55; }

@media (prefers-reduced-motion: reduce) {
  .scene > i { transform: none !important; will-change: auto !important; }
}
@media print { .scene { display: none !important; } }

/* ---------- Website hero ---------- */
.hero--scene { isolation: isolate; }
.hero--scene::before { content: none; }
/* Any other page head that carries the scene (pricing, the guides index). */
.scene-host { position: relative; isolation: isolate; }

/* Pricing: a centred head over the plan cards. The horizon crests, level,
   behind the cards and fades out towards the sides; no rings (they would
   run through the heading). */
.scene-host:not(.legal-hero) > .scene {
  --ax: 50%; --ay: 620px; --aw: 1100px; --ah: 200px;
  --R: clamp(900px, 110vw, 1800px);
  --arc-x: var(--ax); --arc-y: calc(460px + var(--R));
  -webkit-mask-image: linear-gradient(transparent, #000 88px, #000 620px, transparent 900px);
  mask-image: linear-gradient(transparent, #000 88px, #000 620px, transparent 900px);
}
.scene-host:not(.legal-hero) > .scene .scene__arc {
  -webkit-mask-image: conic-gradient(from -34deg, transparent, #000 22deg, #000 46deg, transparent 68deg);
  mask-image: conic-gradient(from -34deg, transparent, #000 22deg, #000 46deg, transparent 68deg);
}
.scene-host:not(.legal-hero) > .scene .scene__rings { display: none; }

/* The guides index head is short and its copy runs wide: the horizon
   sweeps up from the bottom edge, right of the copy, to the top right
   corner; the rings sit in that corner. Below 1360px the copy reaches
   that far, so the horizon goes (and the rings below 1200px). */
.legal-hero > .scene {
  --ax: 94%; --ay: 46%; --aw: 300px; --ah: 260px;
  /* the head is white, which no wash lightens: keep the tint off the copy */
  --wash-x: -16%; --wash-y: -70%;
  --R: clamp(560px, 50vw, 900px);
  --arc-x: calc(100% + var(--R) * .37); --arc-y: calc(100% + var(--R) * .55);
  --ring-s: clamp(600px, 64vw, 900px);
  -webkit-mask-image: linear-gradient(transparent, #000 40px);
  mask-image: linear-gradient(transparent, #000 40px);
}
@media (max-width: 1359px) { .legal-hero > .scene .scene__arc { display: none; } }
@media (max-width: 1199px) { .legal-hero > .scene .scene__rings { display: none; } }

/* ---------- Portal header band ----------
   Rendered once as the first child of .main: the scene sits behind the top
   bar and the page header and fades out into the page. Home gets a taller,
   brighter band; other pages a shorter, quieter one. The anchor is the top
   right, where the page header's actions are. */
.scene--home, .scene--band {
  position: relative; inset: auto; flex: none;
  height: var(--sc-band-h); margin-bottom: calc(var(--sc-band-h) * -1);
  --ax: 84%; --ay: 34%; --aw: 340px; --ah: 160px;
  --R: clamp(620px, 70vw, 1100px);
  --arc-x: calc(var(--ax) + var(--R) * .34); --arc-y: calc(var(--ay) + var(--R) * .96);
  --ring-s: clamp(640px, 70vw, 1100px);
  -webkit-mask-image: linear-gradient(#000 55%, transparent);
  mask-image: linear-gradient(#000 55%, transparent);
}
/* the wash stays well off the greeting in the top left */
.scene--home, .scene--band { --wash-x: -18%; --wash-y: -80%; }
/* The page header's copy can run most of the way across: the horizon,
   rings and dots only on wide screens, where they keep to the top right
   corner. Narrower, the band is just the wash. */
@media (max-width: 1279px) {
  .scene--home > :not(.scene__wash), .scene--band > :not(.scene__wash) { display: none; }
}
.scene--home { --sc-band-h: clamp(300px, 34vw, 420px); }
.scene--band { --sc-band-h: clamp(200px, 22vw, 280px); opacity: .75; --ay: 20%; }
.scene--band .scene__rings .rg { display: none; }

/* ---------- Schools sign-in ----------
   The anchor is the sign-in card (measured), so it stands at the centre of
   its own rings with the horizon rising behind it. */
.s-auth__panel:has(> .scene--auth) { position: relative; isolation: isolate; }
.scene--auth {
  --ax: 50%; --ay: 46%; --aw: 440px; --ah: 460px;
  --R: clamp(620px, 70vw, 1000px);
  /* a little low, so the first ring clears the links under the card */
  --ring-y: calc(var(--ay) + 40px);
  --ring-s: clamp(820px, 110vw, 1400px); --ring-mx: 50%;
  -webkit-mask-image: none; mask-image: none;
}

/* ---------- Narrow two-column hero ----------
   The gap between the copy and the card is tight: the horizon leaves the
   card lower down, below the calls to action. */
@media (min-width: 1001px) and (max-width: 1240px) {
  .hero--scene > .scene { --arc-x: calc(var(--ax) + var(--R) * .64); --arc-y: calc(var(--ay) + var(--R) * .87); }
}

/* ---------- Stacked hero (tablets and phones) ----------
   Copy first, the demo card below. The copy stays on calm ground (the wash
   only); the horizon crests just above the card and the rings and dots
   start at its top edge, so the card rises over them as it scrolls in. */
@media (max-width: 1000px) {
  .hero--scene > .scene {
    --R: clamp(760px, 120vw, 1200px);
    --arc-x: calc(var(--ax) + var(--R) * .3);
    --arc-y: calc(var(--ay) - var(--ah) / 2 - 28px + var(--R));
    --ring-y: calc(var(--ay) - var(--ah) / 2 + 120px);
    --ring-s: clamp(760px, 190vw, 1500px);
  }
  .hero--scene > .scene .scene__rings .rg { display: none; }
  /* the copy sits above the card: rings and dots start at the card's top
     edge (the rings' centre is 120px below it, at 50% of the layer) */
  .hero--scene > .scene .scene__rings {
    -webkit-mask-image: linear-gradient(transparent calc(50% - 160px), #000 calc(50% - 90px));
    mask-image: linear-gradient(transparent calc(50% - 160px), #000 calc(50% - 90px));
  }
  .hero--scene > .scene .scene__grid {
    -webkit-mask-image: linear-gradient(transparent calc(var(--ay) - var(--ah) / 2 - 40px), #000 calc(var(--ay) - var(--ah) / 2 + 60px));
    mask-image: linear-gradient(transparent calc(var(--ay) - var(--ah) / 2 - 40px), #000 calc(var(--ay) - var(--ah) / 2 + 60px));
  }
}
@media (max-width: 760px) {
  .scene { --G: 60px; }
  .scene__rings .rg { display: none; }
}
