/* ============================================================
   NativeOffice - /students promo page
   Create · Analyze · Present

   Deliberately not the main site's look. index.html is a dark
   aurora/glass surface; this is a light paper poster: warm stock,
   heavy ink, highlighter yellow, hard edges instead of glass.
   What carries over so it still reads as NativeOffice: Sora for
   display, Inter for body, and the blue/indigo/violet brand
   gradient as the one shared accent.

   Self-contained on purpose. It does not load css/style.css, so
   nothing here can drag the dark theme's globals onto the page
   (or be broken by a later change to them).

   Motion is a first-class part of the design here, not decoration
   bolted on: the offer should feel like something being handed
   over. Everything animated is gated behind prefers-reduced-motion
   at the bottom of this file.
   ============================================================ */

:root {
  --paper: #fbf8f3;
  --paper-2: #f4efe6;
  --card: #ffffff;
  --ink: #14121a;
  --ink-dim: #57525f;
  --ink-faint: #8b8593;
  --line: rgba(20, 18, 26, 0.12);
  --line-hard: rgba(20, 18, 26, 0.85);

  --hi: #ffd84d;           /* highlighter */
  --hi-deep: #f5b800;
  --go: #0f9d58;           /* granted / confirmed */
  --go-soft: #e7f6ed;

  --blue: #4f8bff;
  --indigo: #5b6cff;
  --violet: #8b5cf6;
  --grad-brand: linear-gradient(120deg, #4f8bff, #5b6cff 45%, #8b5cf6);

  --font-display: "Sora", "Segoe UI", sans-serif;
  --font-body: "Inter", "Segoe UI", sans-serif;

  --wrap: 1140px;
}

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

/* The UA stylesheet's [hidden] rule is display:none at the lowest
   precedence, so ANY author display declaration silently defeats it.
   .stu-claimed sets display:flex, which used to leave the confirmation
   panel on screen for every visitor including signed-out ones. Author
   level and !important so no later rule can reintroduce that. */
[hidden] { display: none !important; }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Ruled-paper grid, fixed so it reads as the stock the page is printed
   on rather than something that scrolls with the content. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background-image:
    linear-gradient(var(--line) 1px, transparent 1px),
    linear-gradient(90deg, var(--line) 1px, transparent 1px);
  background-size: 96px 96px;
  opacity: 0.5;
  mask-image: radial-gradient(ellipse 80% 60% at 50% 0%, #000 20%, transparent 75%);
  -webkit-mask-image: radial-gradient(ellipse 80% 60% at 50% 0%, #000 20%, transparent 75%);
}

/* Slow drifting colour behind the paper. Low opacity on a light ground,
   so it reads as warmth in the stock rather than as a gradient. */
.stu-glow {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
}
.stu-glow i {
  position: absolute;
  display: block;
  width: 46vw;
  height: 46vw;
  border-radius: 50%;
  filter: blur(90px);
  opacity: 0.15;
}
.stu-glow i:nth-child(1) { background: var(--blue); top: -16vw; left: -8vw; animation: drift 24s ease-in-out infinite alternate; }
.stu-glow i:nth-child(2) { background: var(--violet); top: 26vw; right: -12vw; animation: drift 30s ease-in-out infinite alternate-reverse; }
.stu-glow i:nth-child(3) { background: var(--hi); bottom: -18vw; left: 24vw; opacity: 0.22; animation: drift 27s ease-in-out infinite alternate; }

@keyframes drift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(4vw, 5vw, 0) scale(1.15); }
}

img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; cursor: pointer; background: none; border: none; }

.wrap { width: min(100% - 40px, var(--wrap)); margin-inline: auto; }

/* ---------- scroll reveal ---------- */
/* .reveal on its own does NOTHING: elements are fully visible by default.
   The hiding only switches on once js/students.js has put .stu-motion on
   <html>, which it does immediately before it starts watching scroll.

   That ordering is the whole point. Content must never be able to end up
   permanently invisible because a script failed to load, threw early, or ran
   in an environment where the reveal never triggers. The worst case here is
   that the animation is skipped and everything is simply on screen. */
.stu-motion .reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.6s cubic-bezier(0.2, 0.7, 0.3, 1),
              transform 0.6s cubic-bezier(0.2, 0.7, 0.3, 1);
  will-change: opacity, transform;
}
.stu-motion .reveal.in { opacity: 1; transform: none; }

/* ---------- top bar ---------- */
.stu-top {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 22px 0;
}
.stu-brand { display: flex; align-items: center; gap: 10px; font-family: var(--font-display); font-weight: 800; font-size: 19px; letter-spacing: -0.02em; }
.stu-brand img { width: 28px; height: 28px; border-radius: 7px; }
.stu-brand .two { background: var(--grad-brand); -webkit-background-clip: text; background-clip: text; color: transparent; }
.stu-back { font-size: 14px; font-weight: 500; color: var(--ink-dim); border-bottom: 1px solid var(--line); padding-bottom: 1px; }
.stu-back:hover { color: var(--ink); border-color: var(--line-hard); }

/* ---------- hero ---------- */
.stu-hero { position: relative; z-index: 1; padding: 30px 0 58px; }

.stu-hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: 56px;
  align-items: center;
}

.stu-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 7px 14px 7px 10px;
  border: 1.5px solid var(--line-hard);
  border-radius: 999px;
  background: var(--hi);
  box-shadow: 3px 3px 0 var(--ink);
  margin-bottom: 24px;
}
.stu-eyebrow svg { width: 16px; height: 16px; }
.stu-eyebrow .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--ink);
  animation: pulse 1.9s ease-in-out infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.35; transform: scale(0.7); } }

.stu-hero h1 {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(40px, 5.6vw, 70px);
  line-height: 1.02;
  letter-spacing: -0.035em;
}

/* Highlighter swipe: sits behind the words, slightly rotated, and is drawn
   left to right on load the way a marker is actually dragged. */
.mark { position: relative; white-space: nowrap; }
.mark::before {
  content: "";
  position: absolute;
  left: -0.06em;
  right: -0.06em;
  top: 0.14em;
  bottom: 0.06em;
  background: var(--hi);
  transform: rotate(-1.1deg);
  transform-origin: left center;
  z-index: -1;
  border-radius: 3px;
  animation: swipe 0.75s cubic-bezier(0.3, 0.8, 0.35, 1) 0.25s both;
}
@keyframes swipe {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}

/* Slow shimmer across the gradient word, so the one coloured thing in the
   headline is the one that moves. */
.stu-hero h1 .free,
.stu-close h2 .free {
  background: linear-gradient(100deg, #4f8bff, #8b5cf6 30%, #4f8bff 60%, #8b5cf6);
  background-size: 300% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: shimmer 7s linear infinite;
}
@keyframes shimmer { to { background-position: -300% 0; } }

.stu-sub { margin-top: 22px; font-size: clamp(16.5px, 1.5vw, 19px); color: var(--ink-dim); max-width: 52ch; }

/* Rotating use case. Fixed height so nothing reflows as the word swaps. */
.stu-rotator {
  margin-top: 14px;
  font-size: 16.5px;
  font-weight: 600;
  color: var(--ink);
  display: flex;
  align-items: baseline;
  gap: 8px;
  height: 28px;
  overflow: hidden;
}
.stu-rotator .lead { color: var(--ink-faint); font-weight: 500; }
.stu-rot-word {
  display: inline-block;
  background: var(--grad-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-weight: 700;
}
.stu-rot-word.swap { animation: rotWord 0.42s cubic-bezier(0.3, 0.8, 0.35, 1); }
@keyframes rotWord {
  0%   { opacity: 0; transform: translateY(14px); }
  100% { opacity: 1; transform: none; }
}

.stu-cta-row { margin-top: 32px; display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }

.stu-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 11px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.01em;
  color: #fff;
  background: var(--ink);
  border: 2px solid var(--ink);
  border-radius: 14px;
  padding: 17px 28px;
  box-shadow: 5px 5px 0 var(--hi-deep);
  overflow: hidden;
  transition: transform 0.14s cubic-bezier(0.3, 0.8, 0.35, 1), box-shadow 0.14s ease;
}
.stu-btn:hover { transform: translate(-2px, -2px); box-shadow: 7px 7px 0 var(--hi-deep); }
.stu-btn:active { transform: translate(2px, 2px); box-shadow: 2px 2px 0 var(--hi-deep); }
.stu-btn[disabled] { opacity: 0.55; cursor: default; transform: none; box-shadow: 5px 5px 0 var(--hi-deep); }
.stu-btn svg { width: 20px; height: 20px; }
.stu-btn .g { background: #fff; border-radius: 50%; padding: 3px; width: 26px; height: 26px; flex: none; }

/* Light sweeping across the button, on a long loop so it reads as a nudge
   rather than a flashing advert. */
.stu-btn::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  width: 55%;
  left: -60%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.28), transparent);
  animation: sweep 4.5s ease-in-out infinite;
  pointer-events: none;
}
.stu-btn[disabled]::after { display: none; }
@keyframes sweep { 0%, 55% { left: -60%; } 100% { left: 130%; } }

.stu-fine { font-size: 14.5px; color: var(--ink-faint); max-width: 28ch; line-height: 1.5; }
.stu-fine b { color: var(--ink-dim); font-weight: 600; }

/* ---------- hero art: ticket + stickers ---------- */
.stu-hero-art { position: relative; }

.stu-ticket {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 168px;
  background: var(--card);
  border: 2px solid var(--ink);
  border-radius: 20px;
  box-shadow: 12px 12px 0 rgba(20, 18, 26, 0.1);
  overflow: hidden;
  transform: rotate(-1.6deg);
  animation: bob 7s ease-in-out infinite;
}
@keyframes bob {
  0%, 100% { transform: rotate(-1.6deg) translateY(0); }
  50%      { transform: rotate(-1.6deg) translateY(-11px); }
}
.stu-ticket-main { padding: 28px 26px; }
.stu-ticket-label { font-size: 11.5px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-faint); }
.stu-ticket-main h2 { font-family: var(--font-display); font-weight: 800; font-size: 24px; letter-spacing: -0.03em; margin: 8px 0 10px; line-height: 1.15; }
.stu-ticket-main p { color: var(--ink-dim); font-size: 15px; line-height: 1.55; }

.stu-ticket-stub {
  position: relative;
  border-left: 2px dashed var(--line-hard);
  background: var(--paper-2);
  display: grid;
  place-content: center;
  text-align: center;
  padding: 24px 14px;
}
.stu-ticket-stub::before,
.stu-ticket-stub::after {
  content: "";
  position: absolute;
  left: -13px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--paper);
  border: 2px solid var(--ink);
}
.stu-ticket-stub::before { top: -14px; }
.stu-ticket-stub::after { bottom: -14px; }
.stu-stub-num {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 52px;
  line-height: 1;
  letter-spacing: -0.05em;
  background: var(--grad-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-variant-numeric: tabular-nums;
}
.stu-stub-unit { font-family: var(--font-display); font-weight: 700; font-size: 13.5px; letter-spacing: 0.01em; margin-top: 4px; }
.stu-stub-cost { margin-top: 10px; font-size: 12px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--go); }

/* Stickers: rotated, offset, deliberately a bit slapdash. */
.stu-sticker {
  position: absolute;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 13px;
  letter-spacing: 0.01em;
  padding: 10px 16px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: var(--card);
  box-shadow: 4px 4px 0 var(--ink);
  white-space: nowrap;
  z-index: 3;
}
.stu-sticker.s1 { top: -22px; left: -14px; background: var(--hi); transform: rotate(-7deg); animation: bob2 6s ease-in-out infinite; }
.stu-sticker.s2 { bottom: -20px; left: 26px; background: #d8e6ff; transform: rotate(5deg); animation: bob2 6.8s ease-in-out infinite 0.6s; }
.stu-sticker.s3 { top: 42%; right: -26px; background: #e6dcff; transform: rotate(8deg); animation: bob2 7.4s ease-in-out infinite 1.1s; }
@keyframes bob2 {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 -9px; }
}

/* ---------- marquee ---------- */
/* Two identical tracks side by side, the pair translated by exactly -50%,
   which is what makes the loop seamless without measuring anything. */
.stu-marquee {
  margin: 8px 0 0;
  border-top: 2px solid var(--ink);
  border-bottom: 2px solid var(--ink);
  background: var(--ink);
  color: var(--paper);
  overflow: hidden;
  padding: 14px 0;
}
.stu-marquee-inner { display: flex; width: max-content; animation: marquee 26s linear infinite; }
.stu-marquee:hover .stu-marquee-inner { animation-play-state: paused; }
.stu-marquee-track { display: flex; align-items: center; gap: 34px; padding-right: 34px; }
.stu-marquee span {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 34px;
}
.stu-marquee span::after {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--hi);
  flex: none;
}
@keyframes marquee { to { transform: translateX(-50%); } }

/* ---------- claimed state ---------- */
.stu-claimed {
  margin-top: 34px;
  border: 2px solid var(--go);
  background: var(--go-soft);
  border-radius: 18px;
  padding: 26px 30px;
  display: flex;
  gap: 18px;
  align-items: flex-start;
  animation: popIn 0.5s cubic-bezier(0.2, 0.9, 0.3, 1.2);
}
@keyframes popIn {
  from { opacity: 0; transform: translateY(14px) scale(0.97); }
  to   { opacity: 1; transform: none; }
}
.stu-claimed > svg { width: 30px; height: 30px; color: var(--go); flex: none; margin-top: 2px; }
.stu-claimed h3 { font-family: var(--font-display); font-weight: 800; font-size: 22px; letter-spacing: -0.02em; margin-bottom: 5px; }
.stu-claimed p { color: #2c5c42; font-size: 16px; }
.stu-claimed .stu-expiry { font-weight: 700; color: #14432c; }
.stu-claimed-next { margin-top: 14px; display: flex; gap: 12px; flex-wrap: wrap; }
.stu-mini {
  font-size: 14.5px;
  font-weight: 650;
  padding: 9px 16px;
  border: 1.5px solid var(--go);
  border-radius: 10px;
  color: #14432c;
  background: #fff;
  transition: background 0.15s ease, color 0.15s ease;
}
.stu-mini:hover { background: var(--go); color: #fff; }

/* ---------- confetti ---------- */
/* DOM particles, removed by the script once the animation ends. No canvas
   and no library for a two second flourish. */
.stu-confetti { position: fixed; inset: 0; pointer-events: none; z-index: 80; overflow: hidden; }
.stu-confetti i {
  position: absolute;
  top: -14px;
  width: 9px;
  height: 15px;
  border-radius: 2px;
  animation: fall linear forwards;
}
@keyframes fall {
  from { transform: translateY(-10vh) rotate(0deg); opacity: 1; }
  to   { transform: translateY(108vh) rotate(720deg); opacity: 0.9; }
}

/* ---------- sections ---------- */
.stu-sec { padding: 74px 0; border-top: 2px solid var(--line); }
.stu-sec-head { max-width: 60ch; margin-bottom: 40px; }
.stu-sec h2 {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(28px, 4vw, 40px);
  letter-spacing: -0.035em;
  line-height: 1.1;
}
.stu-sec-head p { margin-top: 12px; color: var(--ink-dim); font-size: 17.5px; }

.stu-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 18px; }
.stu-card {
  background: var(--card);
  border: 2px solid var(--ink);
  border-radius: 16px;
  padding: 24px 24px 26px;
  box-shadow: 5px 5px 0 rgba(20, 18, 26, 0.07);
  transition: transform 0.18s cubic-bezier(0.3, 0.8, 0.35, 1), box-shadow 0.18s ease;
}
.stu-card:hover { transform: translate(-3px, -3px); box-shadow: 9px 9px 0 var(--hi-deep); }
.stu-card .ico {
  width: 42px; height: 42px;
  display: grid; place-content: center;
  border-radius: 11px;
  background: var(--paper-2);
  border: 1.5px solid var(--line);
  margin-bottom: 16px;
  transition: background 0.18s ease, transform 0.18s ease;
}
.stu-card:hover .ico { background: var(--hi); transform: rotate(-8deg) scale(1.06); }
.stu-card .ico svg { width: 21px; height: 21px; }
.stu-card h3 { font-family: var(--font-display); font-weight: 700; font-size: 18.5px; letter-spacing: -0.02em; margin-bottom: 7px; }
.stu-card p { font-size: 15.5px; color: var(--ink-dim); line-height: 1.55; }

/* Premium unlocks: a checklist, not cards. It is a short honest list and it
   should look like one. */
.stu-list { display: grid; gap: 2px; max-width: 820px; }
.stu-list li {
  list-style: none;
  display: flex;
  gap: 16px;
  align-items: flex-start;
  padding: 18px 8px;
  border-bottom: 1px solid var(--line);
  border-radius: 10px;
  transition: background 0.16s ease, padding-left 0.16s ease;
}
.stu-list li:first-child { border-top: 1px solid var(--line); }
.stu-list li:hover { background: rgba(255, 216, 77, 0.16); padding-left: 16px; }
.stu-tick {
  flex: none;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--ink);
  color: var(--hi);
  display: grid; place-content: center;
  margin-top: 1px;
}
.stu-tick svg { width: 14px; height: 14px; }
.stu-list b { display: block; font-family: var(--font-display); font-weight: 700; font-size: 17px; letter-spacing: -0.015em; margin-bottom: 2px; }
.stu-list span.txt { font-size: 15.5px; color: var(--ink-dim); }

/* Steps */
.stu-steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 26px; counter-reset: step; }
.stu-step { counter-increment: step; }
.stu-step::before {
  content: counter(step);
  display: grid;
  place-content: center;
  width: 46px; height: 46px;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 20px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: var(--hi);
  box-shadow: 3px 3px 0 var(--ink);
  margin-bottom: 16px;
}
.stu-step h3 { font-family: var(--font-display); font-weight: 700; font-size: 18.5px; letter-spacing: -0.02em; margin-bottom: 6px; }
.stu-step p { font-size: 15.5px; color: var(--ink-dim); }

/* Closing band */
.stu-close {
  position: relative;
  margin: 0 0 80px;
  background: var(--ink);
  color: var(--paper);
  border-radius: 24px;
  padding: clamp(38px, 6vw, 66px);
  text-align: center;
  overflow: hidden;
}
/* Same drifting warmth as the page backdrop, inverted for the dark band. */
.stu-close::before {
  content: "";
  position: absolute;
  width: 60%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, var(--indigo), transparent 65%);
  opacity: 0.4;
  top: -30%;
  left: -10%;
  filter: blur(60px);
  animation: drift 22s ease-in-out infinite alternate;
  pointer-events: none;
}
.stu-close > * { position: relative; }
.stu-close h2 { font-family: var(--font-display); font-weight: 800; font-size: clamp(28px, 4.4vw, 44px); letter-spacing: -0.035em; line-height: 1.08; }
.stu-close p { margin: 16px auto 30px; color: rgba(251, 248, 243, 0.66); max-width: 52ch; }
.stu-close .stu-btn { background: var(--hi); color: var(--ink); border-color: var(--hi); box-shadow: 5px 5px 0 rgba(251, 248, 243, 0.25); }
.stu-close .stu-btn:hover { box-shadow: 7px 7px 0 rgba(251, 248, 243, 0.25); }

/* ---------- sticky CTA ---------- */
/* Appears once the hero button has scrolled away, so the offer is always one
   click off. Hidden again the moment the offer is claimed. */
.stu-dock {
  position: fixed;
  left: 50%;
  bottom: 20px;
  translate: -50% 0;
  display: flex;
  align-items: center;
  gap: 16px;
  background: var(--card);
  border: 2px solid var(--ink);
  border-radius: 16px;
  padding: 11px 12px 11px 20px;
  box-shadow: 6px 6px 0 rgba(20, 18, 26, 0.16);
  z-index: 50;
  opacity: 0;
  transform: translateY(130%);
  transition: opacity 0.3s ease, transform 0.35s cubic-bezier(0.2, 0.9, 0.3, 1.1);
  max-width: calc(100% - 32px);
}
.stu-dock.up { opacity: 1; transform: none; }
.stu-dock-txt { font-family: var(--font-display); font-weight: 700; font-size: 15px; letter-spacing: -0.01em; white-space: nowrap; }
.stu-dock-txt small { display: block; font-family: var(--font-body); font-weight: 500; font-size: 12.5px; color: var(--ink-faint); letter-spacing: 0; }
.stu-dock .stu-btn { padding: 12px 18px; font-size: 15px; box-shadow: 3px 3px 0 var(--hi-deep); }
.stu-dock .stu-btn:hover { box-shadow: 5px 5px 0 var(--hi-deep); }

/* ---------- footer ---------- */
.stu-foot {
  border-top: 2px solid var(--line);
  padding: 32px 0 46px;
  display: flex;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  font-size: 14.5px;
  color: var(--ink-faint);
}
.stu-foot a { border-bottom: 1px solid var(--line); }
.stu-foot a:hover { color: var(--ink); border-color: var(--line-hard); }

/* ---------- toast (session.js expects #toast) ---------- */
.toast {
  position: fixed;
  left: 50%;
  bottom: 28px;
  transform: translate(-50%, 20px);
  background: var(--ink);
  color: var(--paper);
  font-size: 15px;
  font-weight: 500;
  padding: 13px 22px;
  border-radius: 12px;
  box-shadow: 0 12px 34px -10px rgba(0, 0, 0, 0.5);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
  z-index: 90;
  max-width: calc(100% - 40px);
  text-align: center;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ---------- responsive ---------- */
@media (max-width: 940px) {
  .stu-hero-grid { grid-template-columns: 1fr; gap: 62px; }
  .stu-hero-art { margin-inline: auto; max-width: 520px; width: 100%; }
  .stu-fine { max-width: none; }
}

@media (max-width: 720px) {
  body { font-size: 16px; }
  .stu-hero { padding-bottom: 40px; }
  .stu-ticket { grid-template-columns: 1fr; transform: rotate(-1deg); animation: none; }
  .stu-ticket-stub {
    border-left: none;
    border-top: 2px dashed var(--line-hard);
    padding: 22px;
  }
  .stu-ticket-stub::before,
  .stu-ticket-stub::after { left: auto; top: -14px; bottom: auto; }
  .stu-ticket-stub::before { left: -14px; }
  .stu-ticket-stub::after { right: -14px; }
  .stu-sticker.s1 { top: -18px; left: -6px; }
  .stu-sticker.s2 { bottom: -16px; left: 12px; }
  .stu-sticker.s3 { display: none; }
  .stu-sec { padding: 56px 0; }
  .stu-dock { left: 16px; right: 16px; translate: 0 0; bottom: 14px; justify-content: space-between; padding-left: 16px; }
  .stu-dock.up { transform: none; }
  .stu-dock-txt small { display: none; }
  .toast { bottom: 96px; }
}

/* ---------- reduced motion ---------- */
/* Everything decorative stops. The page keeps its full layout and all of its
   content: nothing here is only reachable through an animation. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .stu-motion .reveal { opacity: 1; transform: none; }
  .stu-ticket { transform: rotate(-1.6deg); }
  .stu-btn::after { display: none; }
  .stu-confetti { display: none; }
}
