/* ============================================================
   OWN YOUR STAGE STUDIO: Brand System
   Built to the Own Your Stage Studio brand sheet (Sep 2026):
   Signature Red, Rose Red, Soft Blush, Warm Neutral, Charcoal,
   Montserrat for headings and emphasis, Lato for body.
   Do not introduce a color, typeface or motion that is not there.

   THE MOTIF IS THE SILK.
   The old system's motif was light -- beams, falloff, pools. The
   brand sheet replaces it with a warm room and a red silk ribbon
   running through it. Both survive here and they are not the same
   device: the silk carries the brand, and light is what the silk
   is lit by. Section 2 (light primitives) is now warm rather than
   amber; section 2b is the silk.

   ARCHITECTURE NOTE (GoHighLevel):
   Every selector is scoped under .oyss so this file can be pasted
   into a GHL Custom Code element without touching the builder UI.
   There is no global reset and no bare element styling.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,400;0,500;0,600;0,700;0,800;1,500;1,600&family=Lato:ital,wght@0,300;0,400;0,700;1,300;1,400&family=Sacramento&display=swap');

.oyss {
  /* --- THE FIVE THE BRAND SHEET NAMES ---------------------------------
     Signature Red is the identity and the action. Rose Red is the same
     red with the lights up: it is what carries on a dark ground, where
     Signature Red measures 2.1:1 and cannot. Charcoal is the wordmark. */
  --red:      #B91C1C;   /* Signature Red   5.96:1 on the ground          */
  --rose:     #E05A5A;   /* Rose Red        4.58:1 on --navy              */
  --blush:    #F9E9E7;   /* Soft Blush      the tint field                */
  --neutral:  #F8F5F2;   /* Warm Neutral    the ground                    */
  --charcoal: #2E2E2E;   /* Charcoal        the wordmark                  */

  /* --- THE SAME FIVE UNDER THE NAMES 4,600 LINES ALREADY USE ----------
     This file was written against the old deck. Rather than rename
     ninety-five call sites and risk missing one, the old names are
     repointed. The role each one plays is unchanged; only the hue moved.
     navy: the dark ground, and the hard type on a light one.
     gold: whatever used to be a line, a rule or a highlight.        */
  --navy:    #1F1E1D;   /* Charcoal taken down until Rose Red clears 4.5:1 */
  --ivory:   #F8F5F2;   /* = Warm Neutral                                  */
  --gold:    #E05A5A;   /* = Rose Red                                      */
  --crimson: #B91C1C;   /* = Signature Red                                 */

  /* --- SUPPORT / STRUCTURE, NEVER IDENTITY --- */
  --ink:     #131211;   /* the floor under the dark ground                 */
  --slate:   #6A625E;   /* warm gray, 5.49:1 on Warm Neutral               */
  --ash:     #E4DAD6;   /* the hairline, warmed off Soft Blush             */
  --white:   #FFFFFF;   /* cards lift off Warm Neutral                     */

  /* Derived. Kept as tokens so the ratios stay honest. */
  --navy-80: rgba(31, 30, 29, .80);
  --navy-60: rgba(31, 30, 29, .60);   /* the scrim minimum */
  --gold-40: rgba(224, 90, 90, .40);
  --gold-18: rgba(224, 90, 90, .18);
  --gold-08: rgba(224, 90, 90, .08);
  --ivory-70: rgba(248, 245, 242, .70);
  --ivory-46: rgba(248, 245, 242, .52);  /* .46 measures 4.39:1, under the 4.5 floor */
  --blush-40: rgba(249, 233, 231, .40);

  /* Focus is Rose Red, not Signature Red: it is the one accent that
     clears 3:1 as a ring on BOTH the ground and the dark ground. */
  --focus:   #E05A5A;

  /* --- TYPE ------------------------------------------------------------
     Montserrat headings, Lato body. The old system split the voice serif
     against sans; this one has no serif, so the split is carried by
     family and weight instead. --serif is the display voice and --sans is
     the reading voice, and the names are kept for the same reason the
     color names were. */
  --serif: 'Montserrat', 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
  --sans:  'Lato', 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
  --script: 'Sacramento', 'Segoe Script', cursive;   /* the signature line, once */

  /* --- LADDER (deck p11). Each step ~1.4x the one below. --- */
  --t-eyebrow: .6875rem;
  --t-caption: .8125rem;
  --t-action:  .875rem;
  --t-body:    1.0625rem;
  --t-lead:    clamp(1.125rem, 1.02rem + .45vw, 1.3125rem);
  --t-heading: clamp(1.6rem, 1.24rem + 1.6vw, 2.35rem);
  --t-display: clamp(2.35rem, 1.5rem + 3.7vw, 4.5rem);

  /* --- RHYTHM --- */
  --gutter: clamp(20px, 5vw, 56px);
  --wrap: 1180px;                  /* content width; grows past 1440, section 47 */
  --bay: clamp(72px, 9vw, 132px);   /* vertical section padding */
  --measure: 34rem;                 /* editorial line length      */

  /* --- MOTION. One curve for light, one for matter. --- */
  --fade-up: cubic-bezier(.22, .85, .3, 1);      /* a fader being pushed */
  --settle:  cubic-bezier(.4, 0, .2, 1);

  font-family: var(--sans);
  font-size: var(--t-body);
  line-height: 1.65;
  font-weight: 400;
  color: var(--navy);
  background: var(--ivory);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.oyss *, .oyss *::before, .oyss *::after { box-sizing: border-box; }
.oyss p, .oyss h1, .oyss h2, .oyss h3, .oyss h4, .oyss ul, .oyss ol, .oyss figure { margin: 0; }
.oyss ul, .oyss ol { padding: 0; list-style: none; }
.oyss img, .oyss svg { display: block; max-width: 100%; }
.oyss a { color: inherit; text-decoration: none; }
.oyss button, .oyss input, .oyss select, .oyss textarea { font: inherit; color: inherit; }

/* ============================================================
   1. THE LADDER
   Six levels, and no more. (deck p11)
   ============================================================ */

.oyss .eyebrow {
  font-family: var(--sans);
  font-size: var(--t-eyebrow);
  font-weight: 600;
  letter-spacing: .26em;       /* +2.6 in small caps labels, deck p10 */
  text-transform: uppercase;
  color: var(--slate);
  margin-bottom: 1.15rem;
}
.oyss .eyebrow--gold { color: #B91C1C; }  /* the deck notes gold on ivory fails 4.5:1;
                                             this is the darkest step that still reads gold
                                             and measures 4.81:1 */
.oyss .dark .eyebrow, .oyss .stage .eyebrow { color: var(--gold); }

.oyss .display {
  font-family: var(--serif);
  font-size: var(--t-display);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -.018em;
  text-wrap: balance;
}
.oyss h1, .oyss h2 {
  font-family: var(--serif);
  font-size: var(--t-heading);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -.012em;
  text-wrap: balance;
}
.oyss h3 {
  font-family: var(--sans);
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -.005em;
}
.oyss .lead {
  font-size: var(--t-lead);
  line-height: 1.56;
  font-weight: 400;   /* Lato 300 is a stop lighter than Work Sans 300 was */
  color: var(--slate);
  max-width: var(--measure);
}
.oyss .dark .lead, .oyss .stage .lead { color: var(--ivory-70); }
.oyss .body { max-width: var(--measure); }
.oyss .caption {
  font-size: var(--t-caption);
  line-height: 1.5;
  color: var(--slate);
}
.oyss .dark .caption, .oyss .stage .caption { color: var(--ivory-46); }

/* The serif states the belief. The sans delivers the instruction. */
.oyss .belief { font-family: var(--serif); font-weight: 700; }

/* ============================================================
   2. LIGHT PRIMITIVES
   Light is the only motif. Beams, falloff and pools. Never a lamp,
   a curtain, a microphone or a proscenium. (deck p14)
   ============================================================ */

/* --- THE RED RULE -----------------------------------------
   Kept as .pool because the class is in eleven pages, but the
   shape changed with the identity. The old deck's ornament was a
   flat gold ellipse, a pool of light. The brand sheet draws a
   short Signature Red rule under every label stack it sets --
   under BOLDER VOICES, under REAL EXPERTISE, under the STUDIO in
   the lockup -- and draws no pool anywhere. So this is a rule.

   Signature Red on a light ground, Rose Red on a dark one, for
   the same reason the mark flips. */
.oyss .pool {
  display: block;
  width: 74px; height: 3px;
  border-radius: 2px;
  background: var(--red);
  margin-top: 1.6rem;
  transform-origin: left center;
}
.oyss .dark .pool, .oyss .stage .pool, .oyss .footer .pool { background: var(--rose); }
.oyss .pool--sm { width: 46px; height: 3px; margin-top: 1.1rem; }

/* --- THE RULE ---------------------------------------------
   Ash Gold divides. It never carries a headline or a logo. */
.oyss .rule { height: 1px; background: var(--ash); border: 0; }
.oyss .dark .rule, .oyss .stage .rule { background: rgba(228, 218, 214, .18); }

/* --- THE FALLOFF ------------------------------------------
   A dark section never has a flat background. It always has a
   light origin: one source, one direction. */
.oyss .dark {
  background: var(--navy);
  color: var(--ivory);
  position: relative;
  isolation: isolate;
}
.oyss .dark::before {
  content: '';
  position: absolute; inset: 0;
  background:
    radial-gradient(115% 78% at 50% -14%, var(--gold-08) 0%, transparent 62%),
    linear-gradient(180deg, transparent 0%, rgba(19, 18, 17, .55) 100%);
  pointer-events: none;
  z-index: -1;
}

/* --- THE BEAM ---------------------------------------------
   The logo icon at architectural scale. A shaft of light and the
   pool it lands on. The beam falls off downward, because light
   does. Environmental beams carry falloff; the LOGO mark stays
   one flat gold. (deck p14 vs p16) */
.oyss .beam {
  position: absolute;
  top: -8%; left: 62%;
  width: min(74vw, 900px);
  aspect-ratio: 1 / 1.5;
  transform: translateX(-50%);
  /* Light desaturates toward white at its core and only shows its color in the
     falloff. A beam built from flat gold at low alpha composites to brown over
     navy and stops reading as light, which is why the top stop is warm white. */
  background: linear-gradient(180deg,
    rgba(255, 236, 230, .26) 0%,
    rgba(239, 134, 134, .15) 28%,
    rgba(224, 90, 90, .06) 60%,
    transparent 88%);
  mix-blend-mode: screen;
  clip-path: polygon(43% 0%, 57% 0%, 100% 100%, 0% 100%);
  /* The clip gives the silhouette; the mask feathers it. A hard diagonal edge
     is the tell that a beam was drawn rather than cast, and light spreads
     softer the further it travels, which is why the mask widens downward. */
  -webkit-mask-image: linear-gradient(90deg, transparent 2%, #000 32%, #000 68%, transparent 98%);
          mask-image: linear-gradient(90deg, transparent 2%, #000 32%, #000 68%, transparent 98%);
  filter: blur(56px);
  opacity: 0;
  pointer-events: none;
  z-index: -1;
}
.oyss .beam--lit { animation: beam-ignite 1150ms var(--fade-up) forwards; }

@keyframes beam-ignite {
  0%   { opacity: 0; clip-path: polygon(49.4% 0%, 50.6% 0%, 53% 100%, 47% 100%); }
  100% { opacity: 1; clip-path: polygon(43% 0%, 57% 0%, 100% 100%, 0% 100%); }
}

/* Where the beam lands. Blooms 220ms after ignition. */
.oyss .landing {
  position: absolute;
  left: 50%; bottom: 0;
  width: min(72vw, 900px); height: 190px;
  transform: translate(-50%, 46%);
  background: radial-gradient(50% 50% at 50% 50%, rgba(255, 232, 226, .16) 0%, rgba(224, 90, 90, .05) 45%, transparent 72%);
  mix-blend-mode: screen;
  opacity: 0;
  pointer-events: none;
  z-index: -1;
}
.oyss .landing--lit { animation: bloom 900ms var(--fade-up) 220ms forwards; }
@keyframes bloom { from { opacity: 0; transform: translate(-50%, 46%) scaleX(.4); }
                   to   { opacity: 1; transform: translate(-50%, 46%) scaleX(1); } }

/* --- THE TRAVELLING POOL ----------------------------------
   A pool of light that follows the pointer across dark sections.
   Subtle by contract: gold at 8%, never a glow, never a flare. */
.oyss .stage { position: relative; isolation: isolate; }
.oyss .stage__pool {
  position: absolute;
  width: 620px; height: 620px;
  border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 50%, var(--gold-08) 0%, transparent 68%);
  transform: translate(-50%, -50%);
  pointer-events: none;
  opacity: 0;
  transition: opacity 500ms var(--settle);
  z-index: -1;
}
.oyss .stage:hover .stage__pool { opacity: 1; }

/* ============================================================
   2b. THE SILK
   ------------------------------------------------------------
   The brand sheet's own motif. A red chiffon ribbon enters at
   the left, opens as it travels, and dissolves before it reaches
   the right edge. It is the one thing on the board that is not
   type, a photograph or a rule, so it is the thing that has to
   be here or the site is only a recolor of the old one.

   It is decoration, so it is a background image and never
   markup, it never sits over reading type, and it runs in three
   places and no more: the closing footer, the field a form sheet
   lands on, and the pull quote. A device used everywhere stops
   being a device.

   silk.svg (beside this file) is generated art, not a photograph: 17 tapered
   ribbons over a left-to-right dissolve, drawn once at 1200x620
   and scaled. Anchored xMinYMax, so it stays pinned to the lower
   left however the box is shaped.
   ============================================================ */

.oyss .silked { position: relative; isolation: isolate; }
.oyss .silked > * { position: relative; z-index: 1; }
.oyss .silked::before {
  content: '';
  position: absolute;
  left: 0; bottom: 0;
  width: 100%;   /* never over 100: the section is already full bleed */
  height: clamp(240px, 62%, 620px);
  background: url('silk.svg') left bottom / 100% 100% no-repeat;
  opacity: .5;
  pointer-events: none;
  z-index: 0;
}

/* On the dark ground the ribbon is the only warmth in the frame,
   so it burns in rather than sitting on top. */
.oyss .dark.silked::before,
.oyss .footer.silked::before { opacity: .42; mix-blend-mode: screen; }

/* Inside the pull quote the panel is already Soft Blush, so the
   ribbon only has the deep end of its own gradient left to say, and
   it stays under the reading block rather than crossing it. */
.oyss .goldfield.silked::before { opacity: .6; height: clamp(170px, 52%, 360px); }

@media (max-width: 620px) {
  /* A phone is a column of text. The ribbon reads as noise behind
     it at that width, so it drops to a wash at the very bottom. */
  .oyss .silked::before { height: clamp(150px, 40%, 300px); opacity: .34; }
  .oyss .goldfield.silked::before { opacity: .5; }
}
@media (prefers-reduced-motion: no-preference) {
  .oyss .silked::before { transition: opacity 700ms var(--settle); }
}
@media print { .oyss .silked::before { display: none; } }


/* ============================================================
   3. THE REVEAL
   Nothing slides. Nothing bounces. Things become visible because
   they are lit. That is the entire motion language.
   ============================================================ */

.oyss [data-lit] {
  opacity: .1;
  filter: brightness(.55);
  transform: translateY(14px);
  transition:
    opacity 900ms var(--fade-up),
    filter 1100ms var(--fade-up),
    transform 900ms var(--fade-up);
}
.oyss [data-lit].lit {
  opacity: 1;
  filter: none;
  transform: none;
}
/* Cue stagger. Light hits one thing at a time. */
.oyss [data-lit][data-cue="1"] { transition-delay:  90ms; }
.oyss [data-lit][data-cue="2"] { transition-delay: 180ms; }
.oyss [data-lit][data-cue="3"] { transition-delay: 270ms; }
.oyss [data-lit][data-cue="4"] { transition-delay: 360ms; }
.oyss [data-lit][data-cue="5"] { transition-delay: 450ms; }
.oyss [data-lit][data-cue="6"] { transition-delay: 540ms; }

/* The pool draws itself open rather than fading in. */
.oyss [data-lit] .pool { transform: scaleX(0); transition: transform 800ms var(--fade-up) 260ms; }
.oyss [data-lit].lit .pool { transform: scaleX(1); }

@media (prefers-reduced-motion: reduce) {
  .oyss [data-lit],
  .oyss [data-lit] .pool { opacity: 1; filter: none; transform: none; transition: none; }
  .oyss .beam, .oyss .landing { opacity: 1; animation: none; }
  .oyss .stage__pool { display: none; }
  .oyss * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ============================================================
   4. STRUCTURE
   ============================================================ */

.oyss .wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 var(--gutter); }
.oyss .wrap--tight { max-width: 56.25rem; }
.oyss .bay { padding: var(--bay) 0; }
.oyss .bay--half { padding: calc(var(--bay) * .58) 0; }
.oyss .light { background: var(--ivory); }
.oyss .paper { background: var(--white); }

.oyss .split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(36px, 5.5vw, 88px);
  align-items: center;
}
.oyss .split--copyfirst { grid-template-columns: .95fr 1.05fr; }
.oyss .cols-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(20px, 2.6vw, 34px); }
.oyss .cols-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(20px, 2.6vw, 34px); }
.oyss .cols-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(16px, 2vw, 26px); }

.oyss .stack-xs > * + * { margin-top: .5rem; }
.oyss .stack-s  > * + * { margin-top: 1rem; }
.oyss .stack    > * + * { margin-top: 1.5rem; }
.oyss .stack-l  > * + * { margin-top: 2.5rem; }

@media (max-width: 860px) {
  .oyss .split, .oyss .split--copyfirst, .oyss .cols-3, .oyss .cols-2 { grid-template-columns: 1fr; }
  .oyss .cols-4 { grid-template-columns: repeat(2, 1fr); }
}

/* ============================================================
   5. ACTION
   One primary per view. Never two crimson buttons competing in
   the same viewport. (deck p13)
   ============================================================ */

.oyss .btn {
  display: inline-flex;
  align-items: center;
  gap: .7rem;
  padding: 1.02rem 1.9rem;
  font-family: var(--sans);
  font-size: var(--t-action);
  font-weight: 600;
  letter-spacing: .13em;
  text-transform: uppercase;
  border: 1px solid transparent;
  border-radius: 2px;
  cursor: pointer;
  position: relative;
  transition: background 260ms var(--settle), color 260ms var(--settle),
              border-color 260ms var(--settle), transform 260ms var(--settle);
}
.oyss .btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }

/* The single thing on the page that must be noticed. */
.oyss .btn--primary { background: var(--crimson); color: var(--white); }
.oyss .btn--primary:hover { background: #A81919; transform: translateY(-1px); }

.oyss .btn--ghost { border-color: var(--navy); color: var(--navy); }
.oyss .btn--ghost:hover { background: var(--navy); color: var(--ivory); }
.oyss .dark .btn--ghost, .oyss .stage .btn--ghost { border-color: rgba(248, 245, 242, .34); color: var(--ivory); }
.oyss .dark .btn--ghost:hover, .oyss .stage .btn--ghost:hover { background: var(--ivory); color: var(--navy); border-color: var(--ivory); }

/* A text action that is not a button. Gold as a line, not a fill. */
.oyss .cue {
  display: inline-flex; align-items: center; gap: .55rem;
  font-size: var(--t-action); font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  padding-bottom: .45rem;
  border-bottom: 1px solid var(--gold-40);
  transition: border-color 260ms var(--settle), gap 260ms var(--settle);
}
.oyss .cue:hover { border-color: var(--gold); gap: .95rem; }
.oyss .cue::after { content: '\2192'; font-size: 1.05em; }

.oyss .actions { display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; }

/* ============================================================
   6. MASTHEAD
   The horizontal lockup exists for headers and email signatures
   only. (deck p16)
   ============================================================ */

.oyss .masthead {
  position: sticky; top: 0; z-index: 90;
  /* The bar is translucent, so the 9px STUDIO in Rose Red is measured
     against what the bar COMPOSITES to, not against the token. Over the
     Warm Neutral ground, --navy at .90 landed on #2C2A29 and the STUDIO
     measured 3.93:1. Ink at .96 lands on #1C1B1A and it measures 4.73:1.
     The same sum is repeated in the tablet override at the foot of
     section 27, which is a separate rule and was a separate bug. */
  background: rgba(19, 18, 17, .96);
  backdrop-filter: saturate(140%) blur(14px);
  -webkit-backdrop-filter: saturate(140%) blur(14px);
  border-bottom: 1px solid rgba(228, 218, 214, .13);
  transition: background 300ms var(--settle);
}
.oyss .masthead__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem; height: 78px;
}
.oyss .masthead nav { display: flex; align-items: center; gap: clamp(1rem, 2.1vw, 2.1rem); }
.oyss .masthead nav a {
  font-size: var(--t-caption);
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ivory-70);
  padding: .4rem 0;
  border-bottom: 1px solid transparent;
  transition: color 220ms var(--settle), border-color 220ms var(--settle);
}
.oyss .masthead nav a:hover { color: var(--ivory); border-color: var(--gold); }
.oyss .masthead nav a[aria-current="page"] { color: var(--ivory); border-color: var(--gold); }
.oyss .masthead .btn { padding: .72rem 1.3rem; font-size: .75rem; }

.oyss .burger {
  display: none;
  background: none; border: 1px solid rgba(248, 245, 242, .3);
  border-radius: 2px; padding: .55rem .8rem;
  color: var(--ivory); cursor: pointer;
  font-size: .7rem; letter-spacing: .16em; text-transform: uppercase;
}

@media (max-width: 1040px) {
  .oyss .burger { display: block; }
  .oyss .masthead nav {
    position: absolute; top: 78px; left: 0; right: 0;
    flex-direction: column; align-items: stretch;
    gap: 0;
    background: var(--navy);
    border-bottom: 1px solid rgba(228, 218, 214, .16);
    padding: .5rem var(--gutter) 1.6rem;
    display: none;
  }
  .oyss .masthead nav.open { display: flex; }
  .oyss .masthead nav a { padding: .95rem 0; border-bottom: 1px solid rgba(228, 218, 214, .1); }
  .oyss .masthead nav .btn { margin-top: 1.1rem; justify-content: center; }
}

/* ============================================================
   7. THE LOGO
   The brand sheet's lockup, set rather than placed. OWN YOUR in
   Montserrat 500, STAGE in 800, the A of STAGE replaced by the
   mark, and STUDIO tracked out under it.

   The A is drawn because in this identity it IS the mark: two
   parallel strokes at a 2:1 rise with a flat apex, and an arch
   in the counter where an A has a crossbar. Geometry measured
   off the sheet's ICON / MARK panel and normalised to a 64 x 58
   box -- outer feet at 0 and 64, stroke 11 wide measured
   horizontally, the void closing at y16, and the arch 11 wide on
   a 5.5 radius sitting at y37.

   It is wider and lighter than the bold letters either side of
   it. That is what the sheet draws, and it is the reason the A
   reads as a mark rather than as a glyph in the wrong weight.

   Two colorways, and only two. Rose Red on the dark ground,
   because Signature Red measures 2.1:1 there and disappears.
   Signature Red with a Charcoal wordmark on a light one, which
   is the primary as the sheet prints it.
   ============================================================ */

.oyss .lockup { display: inline-flex; align-items: center; }
.oyss .lockup__type { display: block; }
.oyss .lockup__name {
  font-family: var(--serif);
  font-size: 1.04rem;
  text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
  color: var(--ivory);
}
.oyss .lockup__own   { font-weight: 500; letter-spacing: .085em; }
.oyss .lockup__stage { font-weight: 800; letter-spacing: .03em; margin-left: .28em; }

/* The mark stands where the A does, on the baseline, with its apex
   level with the caps beside it. Montserrat's caps are .70em; the
   mark carries a hair more so the flat apex reads as a point, and
   it is 64:58, so the width follows. */
.oyss .lockup .mark {
  display: inline-block;
  width: .789em; height: .715em;
  vertical-align: baseline;
  margin: 0 .045em 0 .025em;
}
.oyss .mark__a, .oyss .mark__arch { fill: var(--rose); }

.oyss .lockup__desc {
  font-family: var(--serif);
  font-size: .5rem; font-weight: 600;
  letter-spacing: .58em;              /* to the full width of the wordmark */
  text-transform: uppercase;
  color: var(--rose);
  margin-top: .34rem;
}
.oyss .lockup__what { color: var(--ivory-46); }
/* The primary, for any light ground. */
.oyss .lockup--navy .lockup__name { color: var(--charcoal); }
.oyss .lockup--navy .lockup__what { color: var(--slate); }
.oyss .lockup--navy .lockup__desc { color: var(--red); }
.oyss .lockup--navy .mark__a,
.oyss .lockup--navy .mark__arch { fill: var(--red); }

/* ============================================================
   8. CARDS & PANELS
   Warm White sits on Ivory to lift cards off the page. (deck p12)
   ============================================================ */

.oyss .card {
  background: var(--white);
  border: 1px solid var(--ash);
  border-radius: 3px;
  padding: clamp(24px, 2.6vw, 36px);
  position: relative;
  transition: border-color 320ms var(--settle), transform 320ms var(--settle);
}
.oyss .card:hover { border-color: var(--gold-40); transform: translateY(-3px); }
.oyss .card__index {
  font-family: var(--serif);
  font-size: 1.75rem; font-weight: 700; letter-spacing: .02em;
  color: #B91C1C; line-height: 1;          /* light context is the default */
  margin-bottom: 1.25rem;
}
.oyss .dark .card__index, .oyss .stage .card__index { color: var(--gold); }
/* The card on a dark ground used to be a LIFT: 3.5% Warm Neutral over the
   section, which put it at #262524 and dropped every Rose Red accent inside
   it to 4.18:1. A panel does not have to be brighter than the wall to read
   as a panel -- recessed reads as one just as well, and it buys back the
   headroom, taking the same eyebrow to 4.87:1. */
.oyss .dark .card, .oyss .stage .card {
  background: rgba(19, 18, 17, .55);
  border-color: rgba(228, 218, 214, .15);
}
.oyss .dark .card:hover, .oyss .stage .card:hover { border-color: var(--gold-40); }

/* ============================================================
   9. THE DIMMER LADDER
   The four visibility levels rendered as what they are: an
   intensity ladder. Each cell is literally brighter than the one
   before it. Hover moves the light.
   ============================================================ */

.oyss .dimmer { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2px; margin-top: 2.6rem; }
.oyss .dimmer__cell {
  position: relative;
  padding: clamp(22px, 2.4vw, 34px) clamp(16px, 1.8vw, 24px) clamp(26px, 2.8vw, 38px);
  background: var(--ink);
  border-top: 2px solid rgba(228, 218, 214, .16);
  text-align: left;
  cursor: default;
  overflow: hidden;
  transition: background 420ms var(--settle), border-color 420ms var(--settle);
}
/* Baseline luminance climbs across the ladder. */
.oyss .dimmer__cell:nth-child(1) { background: #0D0C0C; }
.oyss .dimmer__cell:nth-child(2) { background: #161514; }
.oyss .dimmer__cell:nth-child(3) { background: #1F1E1D; }
.oyss .dimmer__cell:nth-child(4) { background: #322F2D; border-top-color: var(--gold); }

.oyss .dimmer__cell::after {   /* the pool that lands on this cell */
  content: '';
  position: absolute; left: 50%; top: -34%;
  width: 150%; aspect-ratio: 1 / .9;
  transform: translateX(-50%) scaleY(.2);
  transform-origin: top;
  background: radial-gradient(50% 50% at 50% 50%, var(--gold-18) 0%, transparent 66%);
  opacity: 0;
  transition: opacity 420ms var(--settle), transform 520ms var(--fade-up);
  pointer-events: none;
}
.oyss .dimmer__cell:hover::after,
.oyss .dimmer__cell:focus-within::after { opacity: 1; transform: translateX(-50%) scaleY(1); }
.oyss .dimmer__cell:hover, .oyss .dimmer__cell:focus-within { border-top-color: var(--gold); }

.oyss .dimmer__n {
  font-family: var(--sans); font-size: var(--t-eyebrow); font-weight: 600;
  letter-spacing: .26em; text-transform: uppercase;
  color: var(--slate);
  transition: color 420ms var(--settle);
}
.oyss .dimmer__cell:nth-child(4) .dimmer__n { color: var(--gold); }
.oyss .dimmer__cell:hover .dimmer__n { color: var(--gold); }
.oyss .dimmer__name {
  font-family: var(--serif); font-size: 1.55rem; font-weight: 700;
  line-height: 1.1; margin: .85rem 0 .7rem;
  color: rgba(248, 245, 242, .38);
  transition: color 420ms var(--settle);
}
.oyss .dimmer__cell:nth-child(2) .dimmer__name { color: rgba(248, 245, 242, .55); }
.oyss .dimmer__cell:nth-child(3) .dimmer__name { color: rgba(248, 245, 242, .74); }
.oyss .dimmer__cell:nth-child(4) .dimmer__name { color: var(--ivory); }
.oyss .dimmer__cell:hover .dimmer__name,
.oyss .dimmer__cell:focus-within .dimmer__name { color: var(--ivory); }
.oyss .dimmer__note { font-size: var(--t-caption); line-height: 1.5; color: var(--ivory-46); }

@media (max-width: 780px) { .oyss .dimmer { grid-template-columns: repeat(2, 1fr); } }

/* ============================================================
   10. THE CUE SHEET
   The client journey, rendered the way a production is actually
   run: as a numbered cue stack with a light travelling down it.
   ============================================================ */

.oyss .cuesheet { position: relative; margin-top: 3.4rem; }
.oyss .cuesheet__rail {
  position: absolute; left: 0; top: 0; bottom: 0; width: 1px;
  background: rgba(228, 218, 214, .18);
}
.oyss .cuesheet__marker {
  position: absolute; left: -3px; width: 7px; height: 7px;
  border-radius: 50%; background: var(--gold);
  transition: top 240ms var(--settle);
  box-shadow: 0 0 0 5px rgba(224, 90, 90, .13);
}
.oyss .cuerow {
  display: grid;
  grid-template-columns: 92px 1fr;
  gap: clamp(18px, 3vw, 48px);
  padding: clamp(26px, 3vw, 40px) 0 clamp(26px, 3vw, 40px) clamp(24px, 3vw, 44px);
  border-bottom: 1px solid rgba(228, 218, 214, .13);
}
.oyss .cuerow:last-child { border-bottom: 0; }
.oyss .cuerow__n {
  font-family: var(--serif); font-size: 2.3rem; font-weight: 700;
  letter-spacing: .01em; line-height: .95;
  /* The resting state used to be .45 alpha, which measures 1.85:1
     on ivory. A number the light has not reached yet is still a
     number on the screen, and this is the one numbered sequence
     left on the site, so it is content. .80 measures 3.30:1,
     clears the large-text floor, and the row still visibly
     brightens when the light arrives. */
  color: rgba(185, 28, 28, .80);
  transition: color 600ms var(--settle);
}
.oyss .cuerow.lit .cuerow__n { color: #B91C1C; }
.oyss .dark .cuerow__n, .oyss .stage .cuerow__n { color: rgba(224, 90, 90, .60); }
.oyss .dark .cuerow.lit .cuerow__n,
.oyss .stage .cuerow.lit .cuerow__n { color: var(--gold); }
.oyss .cuerow__label {
  font-family: var(--serif); font-size: 1.5rem; font-weight: 700;
  line-height: 1.15; margin-bottom: .3rem;
}
.oyss .cuerow__claim {
  font-family: var(--sans); font-size: var(--t-eyebrow); font-weight: 600;
  letter-spacing: .26em; text-transform: uppercase;
  color: #B91C1C; margin-bottom: 1rem;     /* 11px text: needs the full 4.5:1 */
}
.oyss .dark .cuerow__claim, .oyss .stage .cuerow__claim { color: var(--gold); }
@media (max-width: 700px) {
  .oyss .cuerow { grid-template-columns: 1fr; gap: .9rem; }
  .oyss .cuerow__n { font-size: 1.9rem; }
}

/* ============================================================
   11. THE PANEL RIG
   Six frames. The light switches between them the way a producer
   switches cameras. This is the deliverable, shown working.
   ============================================================ */

.oyss .rig { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 2.6rem; }
.oyss .frame {
  position: relative;
  aspect-ratio: 16 / 9;
  background: linear-gradient(168deg, #2B2928 0%, #161514 100%);
  border: 1px solid rgba(228, 218, 214, .13);
  border-radius: 2px;
  overflow: hidden;
  display: flex; align-items: flex-end;
  padding: 12px;
  transition: border-color 500ms var(--settle), transform 500ms var(--settle);
}
.oyss .frame::before {   /* the key light, always from above */
  content: '';
  position: absolute; left: 50%; top: -46%;
  width: 118%; aspect-ratio: 1 / 1;
  transform: translateX(-50%);
  background: radial-gradient(50% 50% at 50% 50%, rgba(224, 90, 90, .22) 0%, transparent 64%);
  opacity: 0;
  transition: opacity 620ms var(--settle);
}
.oyss .frame.on::before { opacity: 1; }
.oyss .frame.on { border-color: var(--gold-40); }
.oyss .frame--host { grid-column: span 2; grid-row: span 2; }
.oyss .frame__plate {
  position: relative;
  background: rgba(19, 18, 17, .72);
  border-left: 2px solid var(--gold);
  padding: .5rem .75rem;
  backdrop-filter: blur(4px);
}
.oyss .frame__role {
  font-size: .5625rem; font-weight: 600; letter-spacing: .26em;
  text-transform: uppercase; color: var(--gold); line-height: 1;
}
.oyss .frame__name {
  font-family: var(--serif); font-weight: 700; font-size: 1rem; line-height: 1.2;
  color: var(--ivory); margin-top: .2rem;
}
.oyss .frame--host .frame__name { font-size: 1.4rem; }
.oyss .frame__sub { font-size: .6875rem; color: var(--ivory-46); margin-top: .1rem; }
/* The narrow rig now lives in section 46.1, feedback 5.0. */

/* ============================================================
   12. THE LEDGER
   Division of responsibilities. Two columns that never pretend to
   be neutral: what we hold, and what you hold.
   ============================================================ */

.oyss .ledger { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--ash); border: 1px solid var(--ash); }
.oyss .ledger__col { background: var(--white); padding: clamp(24px, 3vw, 40px); }
.oyss .ledger__col--them { background: var(--ivory); }
.oyss .ledger__head {
  font-size: var(--t-eyebrow); font-weight: 600; letter-spacing: .26em;
  text-transform: uppercase; color: var(--slate);
  padding-bottom: 1rem; margin-bottom: 1.6rem;
  border-bottom: 1px solid var(--ash);
}
.oyss .ledger__col--us .ledger__head { color: #B91C1C; }
.oyss .ticklist li {
  position: relative; padding-left: 1.7rem; font-size: var(--t-caption);
  line-height: 1.5; color: var(--slate);
}
.oyss .ticklist li + li { margin-top: .85rem; }
.oyss .ticklist li::before {   /* the rule, not a checkmark */
  content: ''; position: absolute; left: 0; top: .58em;
  width: 11px; height: 3px; border-radius: 2px; background: var(--red);
}
.oyss .dark .ticklist li::before,
.oyss .stage .ticklist li::before,
.oyss .footer .ticklist li::before { background: var(--rose); }
.oyss .ticklist--none li::before { background: var(--ash); }
.oyss .dark .ticklist li, .oyss .stage .ticklist li { color: var(--ivory-70); }
@media (max-width: 760px) { .oyss .ledger { grid-template-columns: 1fr; } }

/* ============================================================
   13. FIGURES / PRICE
   ============================================================ */

.oyss .figure__value {
  font-family: var(--serif); font-size: clamp(2.6rem, 1.8rem + 3vw, 4rem);
  font-weight: 600; line-height: .95; letter-spacing: -.02em;
}
.oyss .figure__label {
  font-size: var(--t-caption); color: var(--slate); margin-top: .7rem; max-width: 22ch;
}
.oyss .dark .figure__label, .oyss .stage .figure__label { color: var(--ivory-46); }

/* ============================================================
   14. FORMS
   Sans for what the reader has to do. Every field is legible,
   large-target and labelled. The audience is 40+ professionals.
   ============================================================ */

.oyss .field { display: block; }
.oyss .field + .field { margin-top: 1.5rem; }
.oyss .field__label {
  display: block;
  font-size: var(--t-eyebrow); font-weight: 600; letter-spacing: .2em;
  text-transform: uppercase; color: var(--slate); margin-bottom: .6rem;
}
.oyss .dark .field__label, .oyss .stage .field__label { color: var(--ash); }
.oyss .field__input {
  width: 100%;
  padding: .95rem 1.05rem;
  background: var(--white);
  border: 1px solid var(--ash);
  border-radius: 2px;
  font-size: var(--t-body);
  transition: border-color 220ms var(--settle), box-shadow 220ms var(--settle);
}
.oyss .field__input:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px var(--gold-18);
}
.oyss textarea.field__input { min-height: 140px; resize: vertical; }
.oyss .field__help { font-size: var(--t-caption); color: var(--slate); margin-top: .5rem; }
.oyss .field__input[aria-invalid="true"] { border-color: var(--crimson); }

.oyss .check {
  /* 24px, not 20: WCAG 2.2 sets the minimum target at 24x24 and this is a
     consent control, the one place a mis-tap is expensive. */
  display: grid; grid-template-columns: 24px 1fr; gap: .85rem;
  align-items: start; cursor: pointer;
  font-size: var(--t-caption); line-height: 1.55; color: var(--slate);
}
.oyss .check + .check { margin-top: 1.05rem; }
.oyss .check input { width: 24px; height: 24px; margin: 0; accent-color: var(--crimson); cursor: pointer; }

/* Radios rendered as a light ladder rather than dots. */
.oyss .choice { display: block; cursor: pointer; }
.oyss .choice + .choice { margin-top: .6rem; }
.oyss .choice input { position: absolute; opacity: 0; width: 0; height: 0; }
.oyss .choice__box {
  display: grid; grid-template-columns: auto 1fr; gap: .9rem; align-items: center;
  padding: .95rem 1.15rem;
  background: var(--white);
  border: 1px solid var(--ash);
  border-radius: 2px;
  font-size: var(--t-body); line-height: 1.4;
  transition: border-color 200ms var(--settle), background 200ms var(--settle);
}
.oyss .choice__dot {
  width: 16px; height: 6px; border-radius: 50%;
  background: var(--ash);
  transition: background 200ms var(--settle), width 200ms var(--settle);
}
.oyss .choice:hover .choice__box { border-color: var(--gold-40); }
.oyss .choice input:checked + .choice__box { border-color: var(--gold); background: #FFFDFC; }
.oyss .choice input:checked + .choice__box .choice__dot { background: var(--gold); width: 22px; }
.oyss .choice input:focus-visible + .choice__box { outline: 2px solid var(--gold); outline-offset: 2px; }

/* ============================================================
   15. THE DOCUMENT
   Agreements. Editorial legal setting: a real measure, numbered
   sections, red rules. A contract people can actually read.
   ============================================================ */

.oyss .doc { max-width: 42rem; }
.oyss .doc h2 {
  font-family: var(--sans); font-size: var(--t-action); font-weight: 600;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--navy);
  padding-top: 2.6rem; margin-top: 2.6rem;
  border-top: 1px solid var(--ash);
}
.oyss .doc h2:first-child { border-top: 0; padding-top: 0; margin-top: 0; }
.oyss .doc h2 .doc__n { color: #B91C1C; margin-right: .7rem; }  /* 14px on ivory: gold measured 1.89:1 */
.oyss .doc h3 {
  font-size: var(--t-body); font-weight: 600; margin-top: 1.8rem; color: var(--navy);
}
.oyss .doc p { margin-top: 1.05rem; font-size: .9875rem; line-height: 1.72; color: #3C3937; }
.oyss .doc ul { margin-top: 1rem; }
.oyss .doc ul li {
  position: relative; padding-left: 1.5rem; margin-top: .6rem;
  font-size: .9375rem; line-height: 1.62; color: #3C3937;
}
.oyss .doc ul li::before {
  content: ''; position: absolute; left: 0; top: .66em;
  width: 9px; height: 3px; border-radius: 2px; background: var(--red);
}
.oyss .doc strong { font-weight: 600; color: var(--navy); }

/* Sticky contents rail beside the document. */
.oyss .doclayout { display: grid; grid-template-columns: 220px 1fr; gap: clamp(30px, 5vw, 76px); align-items: start; }
.oyss .doctoc { position: sticky; top: 106px; }
.oyss .doctoc a {
  display: block; padding: .42rem 0 .42rem .9rem;
  font-size: var(--t-caption); color: var(--slate);
  border-left: 1px solid var(--ash);
  transition: color 200ms var(--settle), border-color 200ms var(--settle);
}
.oyss .doctoc a:hover, .oyss .doctoc a.here { color: var(--navy); border-left-color: var(--gold); }
@media (max-width: 900px) { .oyss .doclayout { grid-template-columns: 1fr; } .oyss .doctoc { display: none; } }

/* A grid item's default min-width is auto, so the document column was being
   sized by its longest unbreakable token instead of by the screen. That is
   what pushed the agreements 39px wider than a 360px phone. Two belts:
   the track may shrink, and legal prose may break inside a long term. */
.oyss .doclayout > * { min-width: 0; }
.oyss .doc p, .oyss .doc li, .oyss .doc h2, .oyss .doc h3 { overflow-wrap: break-word; }

/* The blank to fill in. A rule, not forty typed underscores. */
.oyss .fill {
  display: inline-block; vertical-align: baseline;
  min-width: 6rem; max-width: 100%; width: 18rem; height: 1em;
  border-bottom: 1px solid var(--slate);
}

/* Reading progress: a beam that fills as the reader descends. */
.oyss .progress { position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 100; background: transparent; }
.oyss .progress__fill { height: 100%; width: 0; background: var(--gold); transition: width 90ms linear; }

/* The signature block. */
.oyss .signblock {
  background: var(--navy); color: var(--ivory);
  padding: clamp(28px, 3.4vw, 48px);
  border-radius: 3px;
  position: relative; overflow: hidden;
}
.oyss .signblock .field__input { background: rgba(248, 245, 242, .07); border-color: rgba(228, 218, 214, .26); color: var(--ivory); }
.oyss .signblock .field__input::placeholder { color: rgba(248, 245, 242, .3); }
.oyss .signblock .check { color: var(--ivory-70); }
.oyss .sig {
  font-family: var(--script); font-weight: 400; font-size: 2.4rem;
  letter-spacing: .01em; line-height: 1; color: var(--rose);
}
.oyss .sig-preview {
  min-height: 78px; display: flex; align-items: center;
  padding: .5rem 1.05rem;
  border-bottom: 1px solid var(--gold-40);
  background: rgba(248, 245, 242, .04);
}
.oyss .locked { opacity: .42; pointer-events: none; transition: opacity 500ms var(--settle); }
.oyss .locked.unlocked { opacity: 1; pointer-events: auto; }

.oyss .fee {
  display: flex; align-items: baseline; gap: 1rem; flex-wrap: wrap;
  padding: 1.5rem 0; border-top: 1px solid var(--gold-40); border-bottom: 1px solid var(--gold-40);
}
.oyss .fee__amt { font-family: var(--serif); font-size: 2.6rem; font-weight: 600; line-height: 1; color: var(--gold); }

/* ============================================================
   16. NOTICES
   ============================================================ */

.oyss .notice {
  padding: 1.15rem 1.35rem;
  border-left: 2px solid var(--gold);
  background: var(--gold-08);
  font-size: var(--t-caption); line-height: 1.6; color: var(--slate);
}
.oyss .notice--action { border-left-color: var(--crimson); background: rgba(185, 28, 28, .05); }
.oyss .dark .notice, .oyss .stage .notice { color: var(--ivory-70); background: rgba(224, 90, 90, .07); }

.oyss .draft-flag {
  display: inline-flex; align-items: center; gap: .6rem;
  padding: .38rem .8rem;
  font-size: .625rem; font-weight: 600; letter-spacing: .2em; text-transform: uppercase;
  color: #B91C1C; background: var(--gold-08); border: 1px solid var(--gold-40); border-radius: 2px;
}

/* ============================================================
   17. FOOTER
   A signature is a business card, not a landing page. (deck p23)
   ============================================================ */

.oyss .footer { background: var(--ink); color: var(--ivory-70); padding: calc(var(--bay) * .7) 0 2.6rem; }
.oyss .footer__grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr; gap: clamp(30px, 4vw, 60px); }
.oyss .footer h4 {
  font-size: var(--t-eyebrow); font-weight: 600; letter-spacing: .26em;
  text-transform: uppercase; color: var(--gold); margin-bottom: 1.3rem;
}
.oyss .footer a { display: block; padding: .34rem 0; font-size: var(--t-caption); color: var(--ivory-70); transition: color 200ms var(--settle); }
.oyss .footer a:hover { color: var(--ivory); }
.oyss .footer__base {
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: 1rem;
  margin-top: 3.6rem; padding-top: 1.7rem;
  border-top: 1px solid rgba(228, 218, 214, .12);
  font-size: var(--t-caption); color: var(--ivory-46);
}
.oyss .footer__promise { font-family: var(--serif); font-weight: 700; font-size: 1.25rem; color: var(--ivory); margin-top: 1.5rem; }
@media (max-width: 760px) { .oyss .footer__grid { grid-template-columns: 1fr; } }

/* ============================================================
   18. UTILITIES
   ============================================================ */

.oyss .sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.oyss .skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--crimson); color: var(--white); padding: .9rem 1.4rem;
  font-size: var(--t-action); font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
}
.oyss .skip:focus { left: 0; }
.oyss .center { text-align: center; }
.oyss .center .lead, .oyss .center .body { margin-left: auto; margin-right: auto; }
.oyss .center .pool { margin-left: auto; margin-right: auto; }
.oyss .hold { max-width: 62rem; }
.oyss .frame-img { border: 1px solid var(--ash); border-radius: 3px; overflow: hidden; background: var(--navy); }

@media print {
  .oyss .masthead, .oyss .footer, .oyss .progress, .oyss .doctoc, .oyss .no-print { display: none !important; }
  .oyss { background: #fff; }
  .oyss .doc { max-width: none; }
  .oyss [data-lit] { opacity: 1 !important; filter: none !important; transform: none !important; }
}

/* Crimson Pro draws the trademark glyph at nearly cap height. Scaled and
   raised here so a product name does not read as a typesetting mistake. */
.oyss .tm {
  font-size: .5em;
  vertical-align: .78em;
  letter-spacing: 0;
  font-weight: 400;
}
/* At display size half an em is still a 29px superscript hanging off the
   end of the headline. It scales down again as the type scales up. */
.oyss .display .tm { font-size: .32em; vertical-align: 1.28em; }
.oyss .eyebrow .tm { font-size: .74em; vertical-align: .32em; }

/* ============================================================
   19. CONTRAST CORRECTIONS
   Found by measuring the rendered page rather than reading the
   stylesheet. Both were invisible in source.
   ============================================================ */

/* `.masthead nav a` (0,3,1) outranks `.btn--primary` (0,2,0), so the header's
   primary CTA was inheriting ivory at 70% over crimson: 3.03:1. */
.oyss .masthead nav a.btn--primary { color: var(--white); }

/* The footer is dark but is not `.dark`, so `.caption` kept its light-context
   slate over Deep Ink: 2.74:1. */
.oyss .footer .caption { color: var(--ivory-46); }
.oyss .footer .ticklist li { color: var(--ivory-46); }

/* The signature block is dark but is not `.dark`, so its field labels kept
   light-context slate over navy: 2.41:1. */
.oyss .signblock .field__label { color: var(--ash); }
.oyss .signblock .field__help  { color: var(--ivory-70); }

/* ============================================================
   20. FULL-BLEED ESCAPE HATCH  (GoHighLevel and similar builders)
   A page builder wraps pasted markup in its own centered, padded
   container, which letterboxes every full-bleed section at the
   container's max-width.

   `50vw` counts the scrollbar but `50%` does not, so the naive
   version overflows horizontally by exactly the scrollbar width.
   Clipping that overflow away also clips the bleed, which is the
   trap: the sections then measure full width and still paint
   inside the container. So the scrollbar is measured in JS and
   subtracted here instead.
   ============================================================ */
.oyss--bleed > header,
.oyss--bleed > footer,
.oyss--bleed > main > section {
  margin-left:  calc(50% - 50vw + (var(--oyss-sbw, 0px) / 2));
  margin-right: calc(50% - 50vw + (var(--oyss-sbw, 0px) / 2));
}

/* ============================================================
   19. RESPONSIVE HARDENING
   Phone, tablet and pointer-type behavior. Every rule below is
   inside a query or a pointer test, so the desktop composition
   the deck specifies is untouched. Still scoped under .oyss so a
   GHL paste stays sealed.
   ============================================================ */

/* iOS inflates text in landscape unless told not to. Scoped, not
   set on html, so the GHL block still carries it. */
.oyss { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* ---- the collapsed masthead -------------------------------- */
@media (max-width: 1040px) {
  /* Anchored to the bar, not to a number. The old top:78px broke
     the moment the masthead changed height. .masthead is sticky,
     so it is already the containing block for this. */
  .oyss .masthead nav {
    top: 100%;
    max-height: calc(100vh - 96px);
    max-height: calc(100svh - 96px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    box-shadow: 0 22px 44px rgba(19, 18, 17, .5);
  }
  .oyss .masthead nav a { min-height: 48px; display: flex; align-items: center; }
  .oyss .burger {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 46px; min-height: 44px; padding: .5rem .7rem;
  }
}

/* ---- tablet ------------------------------------------------ */
@media (max-width: 860px) {
  /* The panel grid already halves at 780/760; the split stack is
     handled above. What is left is the reading rhythm: a stacked
     page needs less air between bays than a two-column one. */
  .oyss { --bay: clamp(62px, 8vw, 104px); }
  .oyss .doclayout { gap: 2rem; }
}

/* ---- phone ------------------------------------------------- */
@media (max-width: 700px) {
  /* 11px small caps survive a desk monitor. They do not survive a
     phone held at arm's length by the audience this sells to. The
     ladder ratio is preserved; only the bottom rung moves. */
  .oyss { --t-eyebrow: .75rem; --gutter: clamp(18px, 5vw, 56px); }
  .oyss .eyebrow,
  .oyss .cuerow__claim,
  .oyss .ledger__head,
  .oyss .footer h4 { letter-spacing: .18em; }
  .oyss .frame__sub { font-size: .75rem; }
  .oyss .figure__label, .oyss .field__help, .oyss .ticklist li { font-size: .8125rem; }

  /* One action per row. A wrapped half-width button next to a
     text cue reads as a mistake at this width. */
  .oyss .actions { flex-direction: column; align-items: stretch; gap: .85rem; }
  .oyss .actions .btn { width: 100%; justify-content: center; }
  .oyss .actions .cue { justify-content: flex-start; }
  .oyss .masthead .btn, .oyss .masthead nav .btn { width: 100%; }

  .oyss .footer__base { flex-direction: column; gap: .6rem; }
  .oyss .footer__promise { font-size: 1.8rem; }

  .oyss .cuerow { padding-left: 0; }
  .oyss .cuesheet__rail, .oyss .cuesheet__marker { display: none; }

  /* A narrow window on a desktop is still a narrow window, and an
     audit measures there. */
  .oyss .field__input { min-height: 48px; }
}

/* ---- small phone ------------------------------------------- */
@media (max-width: 420px) {
  .oyss .dimmer { grid-template-columns: 1fr; }
  .oyss .btn { padding: 1.02rem 1.3rem; letter-spacing: .1em; }
}

/* ---- phone held sideways ----------------------------------- */
@media (max-height: 520px) and (orientation: landscape) {
  .oyss .masthead nav { max-height: calc(100vh - 84px); }
  .oyss { --bay: clamp(46px, 8vh, 84px); }
}

/* ---- touch pointers ---------------------------------------- */
@media (pointer: coarse) {
  /* A 32px underlined cue is legal at 24x24 and still a poor thumb
     target. Padding, not font size, so the type ladder holds. */
  .oyss .cue { padding-top: .55rem; padding-bottom: .7rem; }
  .oyss .footer a { padding: .62rem 0; }
  .oyss .field__input { min-height: 48px; }
}

/* ---- no hover: light cues that can never fire --------------- */
@media (hover: none) {
  /* The pointer-tracked pool has nothing to track. Removing it
     saves the compositing rather than leaving an invisible layer. */
  .oyss .stage__pool { display: none; }
  /* The dimmer's key light is hover-only, so on touch the ladder
     would read as four dead cells. Light them from the token
     scale instead, which is what the deck's dimmer means anyway. */
  .oyss .dimmer__cell:nth-child(3)::after { opacity: .55; transform: translateX(-50%) scaleY(1); }
  .oyss .dimmer__cell:nth-child(4)::after { opacity: 1;   transform: translateX(-50%) scaleY(1); }
  .oyss .dimmer__cell:nth-child(4) { border-top-color: var(--gold); }
}

/* ============================================================
   21. ISSUE PASS, 28 AUG 2026
   Everything below answers a specific, measured complaint from
   the review. Grouped by the complaint so a later reader can see
   why a rule exists, not just what it does.
   ============================================================ */

/* ---- 21.1 THE LOCKUP BROKE IN TWO ---------------------------
   Two separate faults that looked like one.

   (a) `.oyss .footer a` is (0,3,1) and `.oyss .lockup` is (0,2,0),
       so the FOOTER lockup was being served display:block by the
       footer link rule. The icon then stacked above the wordmark.
   (b) `.lockup__name` and `.lockup__desc` were never given a
       display, so they were inline. The two-line lockup on desktop
       was an accident of wrapping, not a rule, and on a phone the
       line broke wherever it happened to run out of room.
   The lockup is artwork. Its proportions are locked in the deck,
   so they are locked here.                                      */
.oyss .lockup,
.oyss .footer .lockup { display: inline-flex; align-items: center; }
.oyss .lockup__type { flex: 0 1 auto; min-width: 0; }
.oyss .lockup__name,
.oyss .lockup__desc { display: block; white-space: nowrap; }

/* ---- 21.2 THE BEAM WAS NOT OVER THE HEADLINE ----------------
   `left: 62%` is a fixed number on a page whose headline column
   is not fixed. On a centered section it landed to the right of
   the words; on a phone it landed off the text entirely. The
   position is now a token, defaulted to the middle and set per
   section by the light engine to the optical center of whatever
   that section's headline block actually is.                    */
.oyss .beam { left: var(--beam-x, 50%); }
.oyss .landing { left: var(--beam-x, 50%); }

/* ---- 21.3 A STACKED CUE DREW A FULL-WIDTH UNDERLINE ---------
   `.actions` becomes a stretch column on a phone, so the cue,
   an inline-flex, was stretched and its gold underline ran the
   whole width with the label sitting at one end. It reads as a
   broken divider. The cue hugs its own text at every width.     */
.oyss .actions .cue { align-self: flex-start; }

/* ---- 21.4 SMALL TYPE -----------------------------------------
   Reviewed at arm's length on a phone, not on a desk monitor.
   The audience is 40+ professionals. Only the bottom two rungs
   of the ladder move; the ratio between them is preserved and
   nothing above body size changes, so the deck's composition is
   intact.                                                       */
.oyss { --t-eyebrow: .75rem; --t-caption: .875rem; }
@media (max-width: 700px) { .oyss { --t-eyebrow: .8125rem; --t-caption: .9375rem; } }

/* The deliverables and "come with" lists were set at caption size
   while carrying primary content. Content gets content size. */
.oyss .ticklist li { font-size: .9375rem; line-height: 1.55; }
@media (max-width: 700px) { .oyss .ticklist li { font-size: 1rem; } }

/* A field label is an instruction, not a caption. */
.oyss .field__label { font-size: .75rem; letter-spacing: .14em; }
@media (max-width: 700px) { .oyss .field__label { font-size: .8125rem; } }
.oyss .check { font-size: .9375rem; }

/* ---- 21.5 ANCHORS LANDED UNDER THE STICKY MASTHEAD ---------- */
.oyss [id] { scroll-margin-top: 128px; }

/* ============================================================
   22. PAGE IDENTITY
   The review: "in mobile all the page design looks exactly the
   same". True, and it was worst where it matters most, because
   an agreement and an application form were reading as two more
   marketing pages.

   So the site now has three page kinds and each one has its own
   silhouette, not just its own words:

     guide      dark hero, content on ivory. The brand voice.
     form       dark hero, then a PAPER SHEET that lifts out of it.
     agreement  dark hero, then a DOCUMENT SHEET with a letterhead.

   The sheet is the tell. A form and a contract are objects you
   fill in and sign, so on this site they are drawn as objects
   sitting on a stage, lit, rather than as page background.
   ============================================================ */

/* ---- 22.1 THE PAGE MARK -------------------------------------
   A cue strip pinned under the masthead. It names the page and
   its kind at all times, which is the thing a phone could not
   answer before. Light bar under a dark masthead on the pages
   that are objects; dark on the pages that are reading.         */
.oyss .pagemark {
  /* Anchored to the bar it sits under, not to the number that bar
     happens to be today. `top: 78px` was already a bug the moment
     the masthead got shorter on a phone: the strip stuck 11px too
     high and the masthead painted over its own page name. The light
     engine measures the masthead and publishes it as --oyss-mh. */
  position: sticky; top: var(--oyss-mh, 78px); z-index: 89;
  border-bottom: 1px solid rgba(228, 218, 214, .16);
  background: var(--navy);
}
.oyss .pagemark__inner {
  display: flex; align-items: center; gap: .8rem;
  min-height: 36px; padding-top: .3rem; padding-bottom: .3rem;
}
.oyss .pagemark__kind {
  font-family: var(--sans);
  font-size: .6875rem; font-weight: 600; letter-spacing: .22em;
  text-transform: uppercase;
  padding: .24rem .55rem;
  border: 1px solid currentColor; border-radius: 2px;
  line-height: 1.3; flex: none;
}
.oyss .pagemark__name {
  font-family: var(--sans);
  font-size: .75rem; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.oyss .pagemark__dot {
  width: 14px; height: 4px; border-radius: 50%;
  background: var(--gold); flex: none;
}

/* guide: the reading pages stay in the dark. */
.oyss .pagemark--guide { background: #161514; }
.oyss .pagemark--guide .pagemark__kind { color: var(--gold); }
.oyss .pagemark--guide .pagemark__name { color: var(--ivory-70); }

/* form and agreement: an ivory strip under a navy masthead. The
   contrast flip is the signal, and it survives being glanced at. */
.oyss .pagemark--form,
.oyss .pagemark--agreement {
  background: var(--ivory);
  border-bottom-color: var(--ash);
  box-shadow: 0 1px 0 var(--gold);
}
.oyss .pagemark--form .pagemark__kind,
.oyss .pagemark--agreement .pagemark__kind { color: #B91C1C; background: var(--gold-08); }
.oyss .pagemark--form .pagemark__name,
.oyss .pagemark--agreement .pagemark__name { color: var(--navy); }
.oyss .pagemark--form .pagemark__dot,
.oyss .pagemark--agreement .pagemark__dot { background: #B91C1C; }

.oyss .pagemark__spacer { margin-left: auto; }
.oyss .pagemark__meta {
  font-size: .6875rem; letter-spacing: .14em; text-transform: uppercase;
  font-weight: 600; color: var(--slate); white-space: nowrap;
}
.oyss .pagemark--guide .pagemark__meta { color: var(--ivory-46); }
@media (max-width: 620px) { .oyss .pagemark__meta { display: none; } }

/* An anchor has to clear both bars, whatever they currently measure. */
.oyss [id] { scroll-margin-top: calc(var(--oyss-mh, 78px) + 52px); }

/* A shorter bar on a phone. The lockup is artwork, so it scales as a
   whole rather than losing its descriptor, and the two sticky bars
   together still leave more than three quarters of the screen. */
@media (max-width: 700px) {
  .oyss .masthead__inner { height: 64px; }
  .oyss .lockup__name { font-size: .92rem; }
  .oyss .lockup__own  { letter-spacing: .07em; }
  .oyss .lockup__desc { font-size: .46rem; letter-spacing: .5em; }
  .oyss .pagemark__inner { min-height: 34px; }
}

/* ---- 22.2 THE SHEET ------------------------------------------
   A form or a contract is an object. It lifts out of the dark
   hero on paper, with a gold head rule where the light lands.    */
.oyss .sheetbay { padding-bottom: var(--bay); background: var(--ivory); }
.oyss .sheet {
  position: relative;
  background: var(--white);
  border: 1px solid var(--ash);
  border-radius: 3px;
  margin-top: calc(-1 * clamp(40px, 6vw, 84px));
  padding: clamp(26px, 3.6vw, 54px);
  box-shadow: 0 30px 70px -46px rgba(19, 18, 17, .75),
              0 2px 0 rgba(31, 30, 29, .03);
  counter-reset: fsec;
}
.oyss .sheet::before {
  content: ''; position: absolute; left: -1px; right: -1px; top: -1px;
  height: 3px; background: var(--gold); border-radius: 3px 3px 0 0;
}
.oyss .sheet--wide { max-width: 62rem; margin-left: auto; margin-right: auto; }

/* The letterhead. Says what the object is before it says anything
   else, which is what a real form or contract does. */
.oyss .sheet__head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1.2rem; flex-wrap: wrap;
  padding-bottom: 1.4rem; margin-bottom: 2.2rem;
  border-bottom: 1px solid var(--ash);
}
.oyss .sheet__title {
  font-family: var(--serif); font-size: clamp(1.4rem, 1.15rem + 1vw, 1.9rem);
  font-weight: 700; line-height: 1.15; color: var(--navy);
}
.oyss .sheet__kicker {
  font-size: var(--t-eyebrow); font-weight: 600; letter-spacing: .22em;
  text-transform: uppercase; color: #B91C1C; margin-bottom: .55rem;
}
.oyss .sheet__meta {
  font-size: var(--t-caption); color: var(--slate);
  text-align: right; line-height: 1.5; min-width: 9rem;
}
.oyss .sheet__meta b { display: block; color: var(--navy); font-weight: 600; }
@media (max-width: 640px) {
  .oyss .sheet__head { display: block; }
  .oyss .sheet__meta { text-align: left; margin-top: 1rem; }
}

/* Section headers inside a sheet are numbered, the way a form is. */
.oyss .sheet__sec {
  counter-increment: fsec;
  display: flex; align-items: baseline; gap: .8rem;
  padding-bottom: .7rem; margin: 3rem 0 1.9rem;
  border-bottom: 1px solid var(--ash);
  font-size: var(--t-eyebrow); font-weight: 600; letter-spacing: .2em;
  text-transform: uppercase; color: var(--navy);
}
.oyss .sheet__sec:first-child { margin-top: 0; }
.oyss .sheet__sec::before {
  content: counter(fsec, decimal-leading-zero);
  font-family: var(--serif); font-weight: 700;
  font-size: 1.35rem; letter-spacing: 0; text-transform: none;
  color: #B91C1C; line-height: 1;
}

/* The action bar. A form ends in a decision, so it gets its own
   ground rather than trailing off into the page. */
.oyss .sheet__foot {
  margin: 2.6rem calc(-1 * clamp(26px, 3.6vw, 54px)) calc(-1 * clamp(26px, 3.6vw, 54px));
  padding: clamp(22px, 2.6vw, 32px) clamp(26px, 3.6vw, 54px);
  background: var(--ivory);
  border-top: 1px solid var(--ash);
  border-radius: 0 0 3px 3px;
}
.oyss .sheet__foot .caption { margin-top: .9rem; }

/* A required-field key, because the form now claims to be one. */
.oyss .sheet__key {
  font-size: var(--t-caption); color: var(--slate);
  padding: .8rem 1.05rem; margin-bottom: 2.2rem;
  background: var(--ivory); border-left: 2px solid var(--gold);
}
.oyss .req { color: var(--crimson); font-weight: 600; }

/* ---- 22.3 THE CONTENTS RAIL ON A PHONE -----------------------
   It was hidden under 900px, which left a fifty clause contract
   with no way to navigate on a phone. It becomes a disclosure at
   the top of the document instead of vanishing.                  */
.oyss .doctoc--mobile { display: none; }
@media (max-width: 900px) {
  .oyss .doctoc--mobile {
    display: block; margin-bottom: 2.4rem;
    border: 1px solid var(--ash); border-radius: 3px; background: var(--ivory);
  }
  .oyss .doctoc--mobile > summary {
    list-style: none; cursor: pointer;
    padding: .95rem 1.1rem;
    font-size: var(--t-eyebrow); font-weight: 600; letter-spacing: .2em;
    text-transform: uppercase; color: var(--navy);
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  }
  .oyss .doctoc--mobile > summary::-webkit-details-marker { display: none; }
  .oyss .doctoc--mobile > summary::after {
    content: ''; width: 16px; height: 4px; border-radius: 50%;
    background: var(--gold); flex: none;
    transition: transform 300ms var(--settle);
  }
  .oyss .doctoc--mobile[open] > summary::after { transform: scaleX(.4); }
  .oyss .doctoc__list { padding: 0 1.1rem 1.1rem; max-height: 46vh; overflow-y: auto; }
  .oyss .doctoc--mobile a {
    display: block; padding: .5rem 0 .5rem .9rem;
    font-size: var(--t-caption); color: var(--slate);
    border-left: 1px solid var(--ash);
  }
}

/* ---- 22.4 THE PARTIES BLOCK ----------------------------------
   A real agreement opens by naming who is bound and by what. The
   reader can answer "what is this and what does it cost" without
   reading a clause.                                              */
.oyss .parties {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: 1px; background: var(--ash);
  border: 1px solid var(--ash); border-radius: 3px;
  margin-top: 0;
}
.oyss .parties > div { background: var(--white); padding: 1rem 1.2rem; }
.oyss .parties dt {
  font-size: var(--t-eyebrow); font-weight: 600; letter-spacing: .2em;
  text-transform: uppercase; color: #B91C1C; margin-bottom: .4rem;
}
.oyss .parties dd { margin: 0; font-size: var(--t-caption); line-height: 1.5; color: var(--navy); }
@media (max-width: 620px) { .oyss .parties { grid-template-columns: 1fr; } }

/* A document sheet holds the two-column doclayout, so the sheet's
   own padding is the page margin and the doc gets a real measure. */
.oyss .docsheet .doclayout { align-items: start; }
.oyss .docsheet .doc { max-width: 40rem; }
.oyss .docsheet .doctoc { top: 132px; }

/* ---- 22.5 A SHEET THAT DOES NOT LIFT -------------------------
   Inside a two-column split there is nothing above to lift out
   of, so the edge alone does the work.                           */
.oyss .sheet--inline { margin-top: 0; }

@media print {
  .oyss .sheet { box-shadow: none; border: 0; margin-top: 0; padding: 0; }
  .oyss .sheet::before, .oyss .pagemark { display: none; }
  .oyss .doctoc--mobile { display: none !important; }
}

/* ============================================================
   23. THE ACCORDION
   The review: the FAQ should collapse. Built on <details> so it
   works with no JavaScript and is keyboard operable for free.
   The open state is expressed as light, not as a chevron
   spinning: the rule lights and the question brightens.
   ============================================================ */

.oyss .qa { border-bottom: 1px solid var(--ash); }
.oyss .qa:first-of-type { border-top: 1px solid var(--ash); }
.oyss .qa > summary {
  list-style: none; cursor: pointer;
  display: grid; grid-template-columns: 1fr auto; gap: 1.2rem;
  align-items: center;
  padding: 1.35rem 0;
  font-family: var(--serif); font-size: 1.25rem; font-weight: 700;
  line-height: 1.3; color: var(--slate);
  transition: color 300ms var(--settle);
}
.oyss .qa > summary::-webkit-details-marker { display: none; }
.oyss .qa > summary:hover { color: var(--navy); }
.oyss .qa > summary:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
.oyss .qa[open] > summary { color: var(--navy); }

/* The switch: a pool of light that widens when the answer opens. */
.oyss .qa__sw {
  width: 26px; height: 6px; border-radius: 50%;
  background: var(--ash); flex: none;
  transition: background 300ms var(--settle), width 300ms var(--settle);
}
.oyss .qa > summary:hover .qa__sw { background: var(--gold-40); }
.oyss .qa[open] .qa__sw { background: var(--gold); width: 38px; }

.oyss .qa__body { padding: 0 0 1.7rem; max-width: var(--measure); }
.oyss .qa__body p + p { margin-top: .9rem; }
.oyss .qa[open] .qa__body { animation: qa-lit 460ms var(--fade-up); }
@keyframes qa-lit { from { opacity: 0; filter: brightness(.6); } to { opacity: 1; filter: none; } }

@media (max-width: 700px) {
  .oyss .qa > summary { font-size: 1.12rem; padding: 1.2rem 0; gap: .9rem; }
  .oyss .qa__sw { width: 22px; }
}
@media (prefers-reduced-motion: reduce) { .oyss .qa[open] .qa__body { animation: none; } }

/* ============================================================
   24. THE DIMMER, ON A PHONE
   The review: "missing scroll effect". Correct. The ladder's key
   light was bound to :hover, so on a touch screen the component
   was four dead cells and the one idea it exists to carry, that
   visibility is a ladder you climb, never fired. It is driven by
   scroll position instead, which is the right trigger on a device
   with no pointer.
   ============================================================ */

.oyss .dimmer__cell.on::after { opacity: 1; transform: translateX(-50%) scaleY(1); }
.oyss .dimmer__cell.on { border-top-color: var(--gold); }
.oyss .dimmer__cell.on .dimmer__n { color: var(--gold); }
.oyss .dimmer__cell.on .dimmer__name { color: var(--ivory); }

@media (hover: none) {
  /* Replaces the static token lift from section 19: a cell climbs
     as it is reached, then holds, so scrolling performs the ladder. */
  .oyss .dimmer__cell:nth-child(3)::after,
  .oyss .dimmer__cell:nth-child(4)::after { opacity: 0; transform: translateX(-50%) scaleY(.2); }
  .oyss .dimmer__cell.on::after { opacity: 1; transform: translateX(-50%) scaleY(1); }
  .oyss .dimmer__cell { transition: background 520ms var(--settle), border-color 520ms var(--settle); }
}

/* The rung the reader landed on, in the assessment result.
   Marked, not merely lit. The ladder's baseline luminance climbs by
   design, so on a result screen an unreached Level 04 is brighter than
   the reached Level 03 and reads as the answer. In a result the rungs
   still ahead are knocked back, and the one reached is named in the
   markup rather than in a pseudo-element, because it is content. */
.oyss .dimmer--result .dimmer__cell::before {
  content: ''; position: absolute; inset: 0;
  background: rgba(13, 12, 12, .62);
  transition: opacity 500ms var(--settle);
  pointer-events: none;
}
.oyss .dimmer--result .dimmer__cell.on::before { opacity: 0; }
.oyss .dimmer--result .dimmer__cell > * { position: relative; z-index: 1; }
.oyss .dimmer__here {
  display: inline-block; margin-top: .9rem;
  padding: .22rem .5rem;
  font-family: var(--sans);
  font-size: .625rem; font-weight: 600; letter-spacing: .2em;
  text-transform: uppercase; color: var(--gold);
  border: 1px solid var(--gold-40); border-radius: 2px;
}

/* ============================================================
   25. THE PANEL RIG, ON A PHONE
   The review: "this section is not clear". At one column the
   frames became tall empty rectangles with a small plate at the
   bottom and a light switching between them that read as nothing.
   On a phone the rig now states what it is: a producer's grid,
   with the live frame marked.
   ============================================================ */

.oyss .frame__live {
  position: absolute; top: 10px; right: 10px;
  display: inline-flex; align-items: center; gap: .38rem;
  padding: .22rem .48rem;
  font-size: .5625rem; font-weight: 600; letter-spacing: .2em; text-transform: uppercase;
  color: var(--gold); background: rgba(19, 18, 17, .62);
  border: 1px solid var(--gold-40); border-radius: 2px;
  opacity: 0; transition: opacity 500ms var(--settle);
}
.oyss .frame__live::before {
  content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--gold);
}
.oyss .frame.on .frame__live { opacity: 1; }

.oyss .rig__note {
  display: flex; align-items: center; gap: .7rem;
  margin-top: 1.2rem;
  font-size: var(--t-caption); color: var(--ivory-46);
}
.oyss .rig__note::before {
  content: ''; width: 16px; height: 3px; border-radius: 2px; background: var(--rose); flex: none;
}

@media (max-width: 760px) {
  /* A 16:9 frame at half a phone's width is 88px tall and has to
     hold a name plate. Squarer frames give the plate somewhere to sit. */
  .oyss .frame { aspect-ratio: 4 / 3; padding: 9px; }
  .oyss .frame--host { aspect-ratio: 16 / 10; }
  .oyss .frame__plate { width: 100%; }
  .oyss .frame__name { font-size: .95rem; }
  .oyss .frame--host .frame__name { font-size: 1.2rem; }
}


/* ============================================================
   26. THE HEADER LOGO, LIT
   The review asked whether the header logo could be a motion
   logo. It can, on the identity's own terms. The mark is an A
   standing on two feet with an arch under it, so it does what a
   thing that stands does: it rises off the baseline, and the
   arch opens under it a beat later. Once on load. It does not
   loop, because a cue that repeats forever stops being a cue and
   becomes a decoration.
   ============================================================ */

.oyss .lockup .mark { transition: filter 320ms var(--settle); }

@media (prefers-reduced-motion: no-preference) {
  .oyss .lockup--motion .mark__a {
    animation: mark-rise 760ms var(--fade-up) both;
  }
  .oyss .lockup--motion .mark__arch {
    animation: arch-bloom 620ms var(--fade-up) 280ms both;
  }
  @keyframes mark-rise {
    0%   { opacity: 0; transform: scaleY(.12); }
    58%  { opacity: 1; }
    100% { opacity: 1; transform: scaleY(1); }
  }
  @keyframes arch-bloom {
    0%   { opacity: 0; transform: scale(.2); }
    100% { opacity: 1; transform: scale(1); }
  }
  .oyss .lockup:hover .mark,
  .oyss .lockup:focus-visible .mark { filter: brightness(1.12); }
}

/* ============================================================
   27. THE FOUNDER PORTRAIT
   Real photography, lit to the brand rather than recolored out
   of recognition: the frame carries the falloff and the key, the
   face is left alone.
   ============================================================ */

.oyss .portrait {
  position: relative; overflow: hidden;
  border: 1px solid var(--ash); border-radius: 3px;
  background: var(--navy);
  aspect-ratio: 4 / 5;
}
.oyss .portrait img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 24%; }
.oyss .portrait::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(76% 56% at 50% -6%, rgba(255, 236, 230, .18) 0%, transparent 58%),
    linear-gradient(180deg, transparent 44%, rgba(19, 18, 17, .30) 100%);
}
.oyss .portrait__plate {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 1.15rem 1.25rem 1.1rem;
  background: linear-gradient(180deg, transparent 0%, rgba(19, 18, 17, .86) 58%);
  color: var(--ivory);
}
.oyss .portrait__plate .eyebrow { color: var(--gold); margin-bottom: .3rem; }
.oyss .portrait__plate .name { font-family: var(--serif); font-weight: 700; font-size: 1.35rem; line-height: 1.15; }

/* ============================================================
   28. THE SPOTLIGHT
   ------------------------------------------------------------
   The old `.beam` was a blurred trapezoid: a wash, not a light.
   The review asked for the spotlight to be above the fold on
   every page, and to move the way the supplied reference moves
   (lignt_effect_and_fare29.mov).

   That reference was measured, not eyeballed. Frames were pulled
   at 10fps and sampled along arcs struck from the cone's apex:

     - the cone half-angle is 43 degrees, constant with depth
     - it holds 19 discrete rays whose ANGLES do not change with
       radius, so they are true radial rays from one source
     - ignition runs zero to full in about 1.1s, with a small
       overshoot at 1.0s before it settles
     - in the steady state total brightness is almost flat (std
       0.78 on a mean of 44) while the frame-to-frame pixel delta
       holds at 3.7, about 8 percent churn. The cone does NOT
       sweep or pulse. Individual rays breathe in place.

   Everything below follows from those numbers. The fans are conic
   gradients whose stops ARE the reference's measured ray angles,
   widths and relative intensities. Three fans drift at different
   rates in opposite directions; superposed they give local
   shimmer with no global movement, which is what the
   frame-difference measurement describes.

   The deck still rules the color. A gold beam over navy
   composites to brown and reads as paint, so the core is warm
   WHITE and only the outermost fan carries gold.
   ============================================================ */

.oyss .spot {
  position: absolute;
  top: 0;
  left: var(--beam-x, 50%);
  width: var(--spot-w, min(190vw, 2000px));
  height: var(--spot-h, 130%);
  transform: translateX(-50%);
  pointer-events: none;
  z-index: -1;

  /* The lamp's RESTING state is on, and there is no CSS transition
     or animation on this element.

     Both were tried and both sat permanently pending: startTime
     stayed null and currentTime stayed 0 while every other
     animation on the page advanced, so a `fill: both` animation
     held its 0% frame and a transition held its start value. The
     lamp was simply never on. This element is 2000px wide and
     carries three blurred conic-gradient layers, blend modes and a
     mask; the compositor never confirms the handoff that a CSS
     animation needs before it can start.

     So ignition is driven a frame at a time from oyss.js instead,
     which needs no handshake. Leaving the resting state LIT also
     means the stage is lit with JavaScript switched off, which is
     the right way round for the one element that carries the
     brand's only motif. */
  opacity: 1;

  /* One mask for the whole rig: light falls off with distance and
     feathers at the edges of the throw. It lives here so the three
     fans and the haze cannot disagree about where the cone ends. */
  -webkit-mask-image: radial-gradient(78% 96% at 50% 0%, #000 0%, rgba(0,0,0,.92) 34%, rgba(0,0,0,.55) 66%, transparent 100%);
          mask-image: radial-gradient(78% 96% at 50% 0%, #000 0%, rgba(0,0,0,.92) 34%, rgba(0,0,0,.55) 66%, transparent 100%);
}

/* --- the three ray fans ------------------------------------ */
.oyss .spot__rays {
  position: absolute; inset: 0;
  transform-origin: 50% 0%;
  mix-blend-mode: screen;
  will-change: transform, opacity;
}

/* The measured fan. */
.oyss .spot__rays--a {
  background: conic-gradient(from 136.0deg at 50% 0%,
    transparent 0deg,
    transparent 4.65deg,
    rgba(255, 242, 238, 0.064) 5.40deg,
    transparent 6.15deg,
    transparent 7.77deg,
    rgba(255, 242, 238, 0.0855) 8.30deg,
    transparent 8.82deg,
    transparent 10.19deg,
    rgba(255, 242, 238, 0.1352) 11.70deg,
    transparent 13.22deg,
    transparent 17.00deg,
    rgba(255, 242, 238, 0.185) 20.00deg,
    transparent 23.00deg,
    transparent 25.05deg,
    rgba(255, 242, 238, 0.1537) 25.60deg,
    transparent 26.16deg,
    transparent 28.55deg,
    rgba(255, 242, 238, 0.1423) 29.00deg,
    transparent 29.45deg,
    transparent 31.25deg,
    rgba(255, 242, 238, 0.1523) 32.90deg,
    transparent 34.55deg,
    transparent 36.67deg,
    rgba(255, 242, 238, 0.1735) 37.50deg,
    transparent 38.33deg,
    rgba(255, 242, 238, 0.175) 41.00deg,
    transparent 44.12deg,
    transparent 44.62deg,
    rgba(255, 242, 238, 0.1722) 46.30deg,
    transparent 47.97deg,
    transparent 53.55deg,
    rgba(255, 242, 238, 0.1565) 54.10deg,
    transparent 54.65deg,
    rgba(255, 242, 238, 0.165) 56.30deg,
    transparent 58.12deg,
    transparent 59.23deg,
    rgba(255, 242, 238, 0.1323) 59.70deg,
    transparent 60.17deg,
    transparent 62.10deg,
    rgba(255, 242, 238, 0.1708) 62.90deg,
    transparent 63.70deg,
    transparent 65.95deg,
    rgba(255, 242, 238, 0.1167) 66.40deg,
    transparent 66.85deg,
    transparent 67.78deg,
    rgba(255, 242, 238, 0.1267) 68.60deg,
    transparent 69.41deg,
    transparent 70.30deg,
    rgba(255, 242, 238, 0.118) 70.80deg,
    transparent 71.30deg,
    transparent 73.15deg,
    rgba(255, 242, 238, 0.1167) 73.60deg,
    transparent 74.05deg,
    transparent 75.74deg,
    rgba(255, 242, 238, 0.1608) 76.90deg,
    transparent 78.06deg,
    transparent 88.00deg);
  filter: blur(7px);
  animation: ray-drift-a 19s ease-in-out infinite alternate,
             ray-haze-a  11s ease-in-out infinite alternate;
}
/* The same rays spread wider and thickened: the near-field haze. */
.oyss .spot__rays--b {
  background: conic-gradient(from 136.0deg at 50% 0%,
    transparent 0deg,
    transparent 12.78deg,
    rgba(255, 232, 226, 0.0484) 13.90deg,
    transparent 15.03deg,
    transparent 17.05deg,
    rgba(255, 232, 226, 0.1023) 19.32deg,
    transparent 21.59deg,
    transparent 30.44deg,
    rgba(255, 232, 226, 0.1163) 31.28deg,
    transparent 32.11deg,
    transparent 35.08deg,
    rgba(255, 232, 226, 0.1152) 37.55deg,
    transparent 40.03deg,
    rgba(255, 232, 226, 0.1324) 44.52deg,
    transparent 49.21deg,
    transparent 54.96deg,
    rgba(255, 232, 226, 0.1184) 55.79deg,
    transparent 56.61deg,
    transparent 59.90deg,
    rgba(255, 232, 226, 0.1001) 60.60deg,
    transparent 61.30deg,
    transparent 65.69deg,
    rgba(255, 232, 226, 0.0883) 66.36deg,
    transparent 67.04deg,
    transparent 69.40deg,
    rgba(255, 232, 226, 0.0893) 70.15deg,
    transparent 70.90deg,
    transparent 73.65deg,
    rgba(255, 232, 226, 0.1217) 75.39deg,
    transparent 77.13deg,
    transparent 88.00deg);
  filter: blur(15px);
  animation: ray-drift-b 27s ease-in-out infinite alternate,
             ray-haze-b  16s ease-in-out infinite alternate;
}
/* The outermost fan is the only one allowed gold, because gold is
   what light does in its falloff, never at its core. */
.oyss .spot__rays--c {
  background: conic-gradient(from 136.0deg at 50% 0%,
    transparent 0deg,
    transparent 0.98deg,
    rgba(239, 134, 134, 0.0462) 1.40deg,
    transparent 1.82deg,
    transparent 11.52deg,
    rgba(239, 134, 134, 0.1) 13.92deg,
    transparent 16.32deg,
    transparent 23.19deg,
    rgba(239, 134, 134, 0.0769) 23.55deg,
    transparent 23.91deg,
    transparent 31.98deg,
    rgba(239, 134, 134, 0.0938) 32.64deg,
    transparent 33.30deg,
    transparent 40.72deg,
    rgba(239, 134, 134, 0.0931) 42.06deg,
    transparent 43.40deg,
    transparent 51.30deg,
    rgba(239, 134, 134, 0.0892) 52.76deg,
    transparent 54.22deg,
    transparent 59.18deg,
    rgba(239, 134, 134, 0.0923) 59.82deg,
    transparent 60.46deg,
    transparent 65.27deg,
    rgba(239, 134, 134, 0.0685) 65.92deg,
    transparent 66.57deg,
    transparent 70.91deg,
    rgba(239, 134, 134, 0.0631) 71.27deg,
    transparent 71.63deg,
    transparent 88.00deg);
  filter: blur(24px);
  animation: ray-drift-c 34s ease-in-out infinite alternate,
             ray-haze-c  22s ease-in-out infinite alternate;
}

/* Fractions of a degree, in opposite directions. Any more and the
   cone visibly swings, which the reference never does. */
@keyframes ray-drift-a { from { transform: rotate(-.55deg); } to { transform: rotate(.55deg); } }
@keyframes ray-drift-b { from { transform: rotate(.9deg);   } to { transform: rotate(-.9deg); } }
@keyframes ray-drift-c { from { transform: rotate(-1.3deg); } to { transform: rotate(1.3deg); } }
@keyframes ray-haze-a  { from { opacity: .82; } to { opacity: 1; } }
@keyframes ray-haze-b  { from { opacity: 1; }   to { opacity: .7; } }
@keyframes ray-haze-c  { from { opacity: .75; } to { opacity: 1; } }

/* --- the source ---------------------------------------------
   The hot point the rays come out of. Without it the fan reads as
   a texture rather than as a lamp that is switched on. */
.oyss .spot__source {
  position: absolute; top: 0; left: 50%;
  width: min(30vw, 380px); aspect-ratio: 2.2 / 1;
  /* Pulled DOWN into the section rather than centered on its top
     edge. The hero starts flush under the sticky masthead, so a
     source sitting on that edge is half clipped by the section's
     own overflow and the lamp reads as a gradient with no origin.
     Two thirds of it is inside the frame now, which is what makes
     the cone look cast rather than painted. */
  transform: translate(-50%, -34%);
  background: radial-gradient(50% 50% at 50% 50%,
    rgba(255, 255, 255, .72) 0%,
    rgba(255, 240, 234, .34) 26%,
    rgba(255, 228, 222, .13) 46%,
    rgba(224, 90, 90, .05) 64%,
    transparent 80%);
  mix-blend-mode: screen;
  filter: blur(7px);
  animation: source-breathe 9s ease-in-out infinite alternate;
}
@keyframes source-breathe { from { opacity: .86; } to { opacity: 1; } }

/* --- the throw ----------------------------------------------
   One soft body of light inside the cone, so the rays sit in
   something instead of floating on the navy. */
.oyss .spot__haze {
  position: absolute; inset: 0;
  background: conic-gradient(from 136.0deg at 50% 0%,
    transparent 0deg,
    rgba(255, 240, 234, .085) 30deg,
    rgba(255, 236, 230, .115) 44deg,
    rgba(255, 240, 234, .085) 58deg,
    transparent 88.0deg);
  mix-blend-mode: screen;
  filter: blur(34px);
}

/* --- where it lands ------------------------------------------
   The review circled the gap between the gold pool and the light
   that is supposed to be casting it. The floor glow is drawn at
   the bottom of the throw on the cone's own axis, so the pool
   sits inside a lit footprint instead of beside one. */
.oyss .spot__floor {
  position: absolute; left: 50%; bottom: 0;
  width: 78%; height: 34%;
  transform: translate(-50%, 30%);
  background: radial-gradient(50% 50% at 50% 50%,
    rgba(255, 236, 230, .17) 0%,
    rgba(224, 90, 90, .07) 42%,
    transparent 72%);
  mix-blend-mode: screen;
  filter: blur(30px);
  opacity: 1;
}

/* The cone is bright enough to matter now, so hero copy is lifted
   above it. Without this the display type sits IN the beam and
   loses contrast exactly where the beam is strongest. */
.oyss .stage > .wrap, .oyss .dark > .wrap { position: relative; z-index: 1; }

/* The pool is the deck's display underline, and under a spotlight it
   is also the place the light lands. The review circled the gap
   between the gold dash and the light supposedly casting it. Inside
   a hero that holds a spot, the pool gets the glow it implies. */
.oyss .stage:has(.spot) .pool,
.oyss .dark:has(.spot) .pool {
  box-shadow: 0 0 22px 7px rgba(224, 90, 90, .16),
              0 0 60px 20px rgba(255, 232, 226, .07);
}

/* Reduced motion: the lamp is on, it simply does not breathe. */
@media (prefers-reduced-motion: reduce) {
  .oyss .spot__rays, .oyss .spot__source { animation: none; }
}

/* Phones: the same lamp, throttled. Three blurred full-bleed
   layers compositing on a mid-range phone is the one place this
   can cost something, so the outer fan goes and the blurs come
   down. The cone reads the same. */
@media (max-width: 700px) {
  .oyss .spot { --spot-w: min(250vw, 940px); }
  .oyss .spot__rays--c { display: none; }
  .oyss .spot__rays--a { filter: blur(5px); }
  .oyss .spot__rays--b { filter: blur(11px); }
  .oyss .spot__haze { filter: blur(24px); }
}

/* ============================================================
   29. THE REEL  (the home hero)
   ------------------------------------------------------------
   Rebuilt against the three sites the client actually linked:
   weandgoliath.com, ovationevents.com, stagingsolutions.com.
   All three open the same way, and it is not the way this site
   opened before:

       TYPE COLUMN  |  FULL-BLEED MEDIA PANEL

   The type owns the left, the picture owns the right and runs
   to the edge of the screen. That is the composition, and it is
   also the fix for a problem the first attempt could not solve:
   the clip is 4:3, and a 4:3 frame stuffed behind a 2.3:1
   desktop hero loses everything that matters in it. In a panel
   that is roughly as tall as it is wide, almost nothing is
   cropped. The doorway, the figure and the floor all survive.

   The clip: a person standing at the base of a tall doorway of
   light, boomeranged into a seamless twenty second loop. The
   client's own words for what the header should be.
   ============================================================ */

.oyss .reel {
  position: relative;
  background: var(--ink);
  overflow: hidden;
  /* Runs up under the masthead: on the home page that bar is
     transparent, so the film starts at the very top of the
     screen the way it does on all three references. */
  margin-top: calc(-1 * var(--oyss-mh, 78px));
  min-height: clamp(560px, 100svh, 940px);
  display: grid;
  grid-template-columns: minmax(0, 1.28fr) minmax(0, 1fr);
  align-items: center;
}

/* --- the type column ---------------------------------------- */
.oyss .reel__copy {
  position: relative;
  z-index: 2;
  padding: calc(var(--oyss-mh, 78px) + clamp(28px, 5vh, 72px)) clamp(28px, 3.4vw, 64px)
           clamp(40px, 7vh, 88px) max(var(--gutter), calc((100vw - var(--wrap)) / 2 + var(--gutter)));
  /* No max-width. It was 48rem with justify-self:end, and because the left
     padding grows with the viewport to stay on the wrap's edge, a fixed box
     width meant the TEXT column got narrower as the screen got wider: 533px
     of measure at 1440, 482 at 1536, 278 at 1920, where the headline broke
     into seven lines. Feedback 6.0: "the title and everything looks very
     contained". The column is the grid track now, and the measure is set
     on the headline and the lead themselves (section 47). */
  width: 100%;
}

/* The category line, keyed with the client's red. A line, not a
   field: the deck allows crimson as a rule and as an action and
   nowhere else, and this is a rule. */
.oyss .eyebrow--keyed {
  display: flex; align-items: flex-start; gap: .8rem;
  color: var(--gold);
  margin-bottom: 1.5rem;
  letter-spacing: .2em;
}
.oyss .eyebrow--keyed::before {
  content: '';
  width: clamp(26px, 3.4vw, 44px); height: 3px;
  margin-top: .52em;
  background: var(--crimson);
  flex: none;
}

.oyss .reel .display {
  font-size: clamp(2.5rem, 1.5rem + 3.5vw, 4.2rem);
  line-height: 1.03;
  text-wrap: balance;
}
.oyss .reel__rule {
  display: block;
  width: 84px; height: 3px;
  background: var(--gold);
  margin: 1.7rem 0 0;
  transform-origin: left center;
}
.oyss [data-lit] .reel__rule { transform: scaleX(0); transition: transform 700ms var(--fade-up) 300ms; }
.oyss [data-lit].lit .reel__rule { transform: scaleX(1); }

.oyss .reel .lead {
  color: rgba(248, 245, 242, .82);
  margin-top: 1.7rem;
  max-width: 30rem;
}
.oyss .reel .actions { margin-top: 2.2rem; }

/* --- the media panel ---------------------------------------- */
.oyss .reel__media {
  position: relative;
  align-self: stretch;
  min-height: 0;
  overflow: hidden;
}
.oyss .reel__media video,
.oyss .reel__media img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center 58%;
}
/* Feathered into the type side, and darkened top and bottom so
   the masthead and the section seam both have something to sit
   on. No box, no card, no rounded corner: the picture is the
   edge of the page. */
.oyss .reel__media::after {
  content: '';
  position: absolute; inset: 0;
  background:
    linear-gradient(to right,
      var(--ink) 0%, rgba(19, 18, 17, .86) 8%, rgba(19, 18, 17, .34) 22%, rgba(19, 18, 17, 0) 44%),
    linear-gradient(to bottom,
      rgba(19, 18, 17, .72) 0%, rgba(19, 18, 17, 0) 22%,
      rgba(19, 18, 17, 0) 78%, rgba(19, 18, 17, .55) 100%);
}
.oyss .reel__still { display: none; }
@media (prefers-reduced-motion: reduce) {
  .oyss .reel__media video { display: none; }
  .oyss .reel__media .reel__still { display: block; }
}

/* --- the masthead, over the film ---------------------------- */
/* On the home page the bar has nothing behind it until you
   scroll. It gains its ground back the moment the film leaves,
   which the light engine drives with .masthead--over. */
.oyss .masthead--over {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-bottom-color: transparent;
}
.oyss .masthead--over .lockup,
.oyss .masthead--over nav a { text-shadow: 0 1px 22px rgba(13, 12, 12, .9); }

/* --- tablet: the panel goes under the copy ------------------ */
@media (max-width: 1040px) {
  .oyss .reel {
    grid-template-columns: 1fr;
    min-height: 0;
    align-items: stretch;
  }
  .oyss .reel__media {
    order: -1;
    height: clamp(340px, 52svh, 560px);
  }
  .oyss .reel__media::after {
    background:
      linear-gradient(to bottom,
        rgba(19, 18, 17, .66) 0%, rgba(19, 18, 17, .06) 26%,
        rgba(19, 18, 17, .30) 68%, rgba(19, 18, 17, .88) 92%, var(--ink) 100%);
  }
  .oyss .reel__copy {
    justify-self: stretch;
    max-width: 46rem;
    margin: 0 auto;
    padding: clamp(26px, 4.5vw, 44px) var(--gutter) clamp(48px, 8vw, 76px);
  }
  /* The head stops running under the bar. On a desktop the media panel is
     600px tall and losing 78px of it behind a transparent masthead costs
     nothing; in a 240px slot on a tablet it is a third of the picture, and
     what it eats is the top of the subject. So below this width the bar takes
     its ground back and the panel starts underneath it. */
  .oyss .reel { margin-top: 0; }
  .oyss .masthead--over {
    /* same sum as section 6: ink, not the dark ground, or the STUDIO
       under it drops back to 3.93:1 */
    background: rgba(19, 18, 17, .97);
    backdrop-filter: saturate(140%) blur(14px);
    -webkit-backdrop-filter: saturate(140%) blur(14px);
    border-bottom-color: rgba(228, 218, 214, .13);
  }

}
@media (max-width: 620px) {
  .oyss .reel__media { height: clamp(260px, 38svh, 380px); }
  .oyss .reel .display { font-size: clamp(2.1rem, 1.35rem + 3.4vw, 2.9rem); }
}

@media (min-width: 1041px) and (max-height: 780px) {
  .oyss .reel__copy {
    padding-top: calc(var(--oyss-mh, 78px) + clamp(14px, 2.4vh, 40px));
    padding-bottom: clamp(28px, 5vh, 60px);
  }
  .oyss .reel .display { font-size: clamp(2.4rem, 1.4rem + 3vw, 3.5rem); }
  .oyss .eyebrow--keyed { margin-bottom: 1.05rem; }
  .oyss .reel__rule { margin-top: 1.25rem; }
  .oyss .reel .lead { margin-top: 1.25rem; }
  .oyss .reel .actions { margin-top: 1.7rem; }
}


/* ============================================================
   30. THE FILM
   ------------------------------------------------------------
   "Create and add a motion style graphic like this."
   "I am thinking of adding a similar type of animated video
    explaining what own your studio offers and does for a person
    so it is more easy to understand."

   Both notes are the same note, so this is one answer to both: a
   twenty five second brand film, made for this site, that walks
   a stranger from "nobody outside my circle has heard of me" to
   "and it keeps working afterwards" in six beats on one stage.
   It is 940KB and it holds the deck's rules: one light source,
   one direction, gold in the falloff, crimson only on the tally
   light that says the show is live.

   It is not decoration and it is not a placeholder. It plays
   when it comes into view, stops when it leaves, and every beat
   it shows is also written underneath it as text, because a
   person who cannot or will not watch a video still has to be
   able to find out what this company does.
   ============================================================ */

.oyss .film { background: var(--ink); position: relative; }
.oyss .film__head { max-width: 44rem; }

.oyss .film__stage {
  position: relative;
  margin-top: clamp(30px, 4vw, 50px);
  border: 1px solid rgba(224, 90, 90, .22);
  background: #0D0C0C;
  overflow: hidden;
  /* the light the frame is standing in */
  box-shadow: 0 0 0 1px rgba(19, 18, 17, .8),
              0 60px 120px -60px rgba(0, 0, 0, .9);
}
.oyss .film__stage video { display: block; width: 100%; height: auto; }

/* One control, bottom left, over the picture. It is a button
   because it does something; it is not a play badge in the
   middle of the frame, because the film is already playing. */
.oyss .film__toggle {
  position: absolute; left: clamp(12px, 1.6vw, 20px); bottom: clamp(12px, 1.6vw, 20px);
  display: inline-flex; align-items: center; gap: .6rem;
  padding: .58rem 1rem;
  background: rgba(19, 18, 17, .72);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(248, 245, 242, .26);
  border-radius: 2px;
  color: var(--ivory);
  font-size: .6875rem; font-weight: 600; letter-spacing: .2em; text-transform: uppercase;
  cursor: pointer;
  transition: background 220ms var(--settle), border-color 220ms var(--settle);
}
.oyss .film__toggle:hover { background: rgba(19, 18, 17, .92); border-color: var(--gold); }
.oyss .film__toggle:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.oyss .film__toggle::before {
  content: ''; width: 8px; height: 9px; flex: none;
  background: var(--gold);
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}
.oyss .film__toggle[data-state="playing"]::before {
  /* two bars: the button will pause it */
  clip-path: polygon(0 0, 34% 0, 34% 100%, 0 100%, 0 0, 66% 0, 100% 0, 100% 100%, 66% 100%, 66% 0);
}

/* The same six beats, in text, under the picture. */
.oyss .beats {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 1px;
  margin-top: clamp(26px, 3.4vw, 42px);
  background: rgba(228, 218, 214, .14);
  border: 1px solid rgba(228, 218, 214, .14);
}
.oyss .beat { background: var(--ink); padding: clamp(16px, 1.7vw, 24px); }
.oyss .beat__n {
  font-size: var(--t-eyebrow); font-weight: 600; letter-spacing: .2em;
  color: var(--gold); margin-bottom: .7rem;
}
.oyss .beat__t {
  font-family: var(--serif); font-weight: 700; font-size: 1.28rem; line-height: 1.2;
  color: var(--ivory); margin-bottom: .5rem;
}
.oyss .beat p { font-size: var(--t-caption); line-height: 1.5; color: var(--ivory-46); }

@media (max-width: 900px) { .oyss .beats { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .oyss .beats { grid-template-columns: 1fr; } }


/* ============================================================
   31. THE COVER CARD
   ------------------------------------------------------------
   "I really like the animation style of this website, especially
    the end CTA showing up to full screen when hovering."

   On ovationevents.com that is a card whose hidden panel slides
   up and takes the whole card. So that is what these do, and the
   panel that arrives carries the thing a card cannot fit: what
   is actually in the box.

   Touch has no hover, so on a phone the card simply prints both
   halves. A detail that only exists on hover does not exist.
   ============================================================ */

.oyss .covers { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(16px, 2vw, 26px); }

.oyss .cover {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: block;
  min-height: clamp(280px, 26vw, 340px);
  padding: clamp(24px, 2.4vw, 34px);
  background: var(--white);
  border: 1px solid var(--ash);
  color: var(--navy);
}
/* The spans inside are laid out as blocks; the card is a link to
   the page that carries the full list, so the hover panel is a
   preview of a real destination and not a dead end. */
.oyss .cover > span { display: block; }
.oyss .cover::before {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: var(--navy);
  transform: translateY(101%);
  transition: transform 620ms cubic-bezier(.16, .84, .28, 1);
}
.oyss .cover:hover::before,
.oyss .cover:focus-visible::before,
.oyss .cover.is-open::before { transform: translateY(0); }
.oyss .cover:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }

.oyss .cover__n {
  font-size: var(--t-eyebrow); font-weight: 600; letter-spacing: .22em;
  text-transform: uppercase; color: #B91C1C;
  transition: color 500ms var(--settle);
}
.oyss .cover__t {
  font-family: var(--serif); font-weight: 700;
  font-size: clamp(1.45rem, 1.15rem + .8vw, 1.85rem); line-height: 1.15;
  margin-top: 1rem;
  transition: color 500ms var(--settle);
}
.oyss .cover__p {
  font-size: var(--t-caption); line-height: 1.55; color: var(--slate);
  margin-top: .9rem;
  transition: color 500ms var(--settle);
}
/* what arrives with the panel */
.oyss .cover__more {
  margin-top: 1.2rem;
  opacity: 0; transform: translateY(10px);
  transition: opacity 380ms var(--settle) 150ms, transform 460ms var(--fade-up) 150ms;
}
.oyss .cover__more li {
  font-size: var(--t-caption); line-height: 1.45;
  color: var(--ivory-70);
  padding: .42rem 0 .42rem 1.15rem;
  position: relative;
  border-top: 1px solid rgba(228, 218, 214, .14);
}
.oyss .cover__more li::before {
  content: ''; position: absolute; left: 0; top: 1.05em;
  width: 6px; height: 2px; background: var(--gold);
}
.oyss .cover:hover .cover__more,
.oyss .cover:focus-visible .cover__more,
.oyss .cover.is-open .cover__more { opacity: 1; transform: none; }

.oyss .cover:hover .cover__n,
.oyss .cover:focus-visible .cover__n,
.oyss .cover.is-open .cover__n { color: var(--gold); }
.oyss .cover:hover .cover__t,
.oyss .cover:focus-visible .cover__t,
.oyss .cover.is-open .cover__t { color: var(--ivory); }
.oyss .cover:hover .cover__p,
.oyss .cover:focus-visible .cover__p,
.oyss .cover.is-open .cover__p { color: var(--ivory-70); }

@media (max-width: 900px) { .oyss .covers { grid-template-columns: 1fr; } }

/* No pointer, or no room: print both halves, panel down, nothing hidden.
   The width clause matters as much as the hover one. A card that reserves
   340px of height for content it will only reveal on hover is 340px of
   nothing on any narrow window, whatever the device claims about pointers. */
@media (hover: none), (max-width: 900px) {
  .oyss .cover { min-height: 0; background: var(--navy); border-color: rgba(224, 90, 90, .2); }
  .oyss .cover::before { transform: translateY(0); }
  .oyss .cover__n { color: var(--gold); }
  .oyss .cover__t { color: var(--ivory); }
  .oyss .cover__p { color: var(--ivory-70); }
  .oyss .cover__more { opacity: 1; transform: none; }
}


/* ============================================================
   32. THE RED
   ------------------------------------------------------------
   "Liking this red color ... see if you can use this red color
    along with Annette brand deck."

   The red the client pointed at is not a flat swatch. It is a
   lit one: measured off her own reference frame it runs from
   #6E1010 in the shadow to #D93030 where the key light hits.
   Sampled, not guessed.

   The deck says crimson is for action and never for mood, so it
   gets exactly one field on the page and that field is the ask.
   Stage Crimson #B91C1C sits between the two sampled values, so
   the deck's own color is the middle of the client's gradient,
   and the button that has always been crimson now sits inside a
   room made of the same light.
   ============================================================ */

.oyss .redstage {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background:
    radial-gradient(120% 90% at 78% 8%, #D93030 0%, #B91C1C 26%, #8C1616 58%, #6E1010 100%);
  color: var(--white);
}
/* the falloff, so it reads as a lit wall and not as a paint chip */
.oyss .redstage::before {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(52% 40% at 76% 4%, rgba(255, 234, 230, .30) 0%, transparent 62%),
    linear-gradient(190deg, transparent 42%, rgba(40, 8, 8, .55) 100%);
}
.oyss .redstage .eyebrow { color: rgba(255, 242, 238, .94); }
.oyss .redstage h2, .oyss .redstage .display { color: var(--white); }
.oyss .redstage .lead { color: rgba(255, 240, 236, .88); }
.oyss .redstage .caption { color: rgba(255, 240, 236, .88); }
.oyss .redstage .rule { background: rgba(255, 236, 232, .3); }
.oyss .redstage .pool { background: var(--white); }

/* On red, the button inverts: ivory fill, crimson type. */
.oyss .redstage .btn--primary { background: var(--white); color: #9E1616; }
.oyss .redstage .btn--primary:hover { background: var(--ivory); color: #6E1010; }
.oyss .redstage .cue { color: var(--white); border-bottom-color: rgba(255, 236, 232, .45); }
.oyss .redstage .cue:hover { border-bottom-color: var(--white); }

/* the ladder, restated on red */
.oyss .rungs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px;
               background: rgba(255, 236, 232, .22); border: 1px solid rgba(255, 236, 232, .22); }
.oyss .rung {
  background: rgba(110, 16, 16, .34);
  padding: clamp(18px, 2vw, 26px);
  transition: background 420ms var(--settle);
}
.oyss .rung:nth-child(2) { background: rgba(110, 16, 16, .26); }
.oyss .rung:nth-child(3) { background: rgba(110, 16, 16, .22); }
.oyss .rung:nth-child(4) { background: rgba(110, 16, 16, .12); }
.oyss .rung:hover { background: rgba(255, 255, 255, .12); }
.oyss .rung__n { font-size: var(--t-eyebrow); font-weight: 600; letter-spacing: .2em;
                 color: rgba(255, 240, 236, .86); }
.oyss .rung__t { font-family: var(--serif); font-weight: 700; font-size: 1.5rem; line-height: 1.1;
                 margin-top: .7rem; color: var(--white); }
.oyss .rung p { font-size: var(--t-caption); line-height: 1.45; margin-top: .55rem;
                color: rgba(255, 240, 236, .88); }
@media (max-width: 860px) { .oyss .rungs { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 460px) { .oyss .rungs { grid-template-columns: 1fr; } }


/* ============================================================
   33. THE FLOOD  (the closing cue)
   ------------------------------------------------------------
   The same hover behavior as the cover cards, at the scale of
   the page: point at the last block and the whole field comes up
   from the floor. Keyboard focus fires the same cue. A device
   with no hover gets the wash already up, because an invitation
   that only appears on hover is an invitation nobody gets.
   ============================================================ */

.oyss .flood {
  position: relative; display: block; overflow: hidden; isolation: isolate;
  background: rgba(31, 30, 29, .38);
  border-top: 1px solid rgba(224, 90, 90, .22);
  border-bottom: 1px solid rgba(224, 90, 90, .22);
  padding: clamp(46px, 6.5vw, 84px) 0;
  cursor: pointer;
}
.oyss .flood::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: radial-gradient(120% 140% at 76% 100%, #D93030 0%, #B91C1C 30%, #8C1616 66%, #6E1010 100%);
  transform: scaleY(0); transform-origin: 50% 100%;
  transition: transform 620ms cubic-bezier(.16, .84, .28, 1);
}
.oyss .flood:hover::before,
.oyss .flood:focus-visible::before { transform: scaleY(1); }
.oyss .flood:focus-visible { outline: 2px solid var(--gold); outline-offset: -4px; }

.oyss .flood__inner { display: flex; align-items: center; justify-content: space-between;
                      gap: clamp(22px, 4vw, 60px); }
.oyss .flood__eyebrow { display: block; font-size: var(--t-eyebrow); font-weight: 600;
                        letter-spacing: .26em; text-transform: uppercase; color: var(--gold);
                        transition: color 420ms var(--settle); }
.oyss .flood__label { display: block; font-family: var(--serif); font-weight: 700;
                      font-size: clamp(1.8rem, 1.15rem + 2.5vw, 3.2rem); line-height: 1.06;
                      letter-spacing: -.018em; color: var(--ivory); margin-top: .65rem;
                      text-wrap: balance; }
.oyss .flood__meta { display: block; font-size: var(--t-caption); font-weight: 600;
                     letter-spacing: .12em; text-transform: uppercase; color: var(--ivory-46);
                     margin-top: 1rem; transition: color 420ms var(--settle); }
.oyss .flood__arrow {
  flex: none; display: grid; place-items: center;
  width: clamp(54px, 6vw, 78px); aspect-ratio: 1;
  border: 1px solid rgba(248, 245, 242, .3); border-radius: 50%;
  color: var(--ivory); font-size: clamp(1.1rem, .9rem + .9vw, 1.6rem); line-height: 1;
  transition: transform 520ms cubic-bezier(.16, .84, .28, 1), border-color 420ms var(--settle),
              background 420ms var(--settle), color 420ms var(--settle);
}
.oyss .flood:hover .flood__arrow,
.oyss .flood:focus-visible .flood__arrow {
  transform: translateX(12px); background: var(--ivory); border-color: var(--ivory); color: #9E1616;
}
.oyss .flood:hover .flood__eyebrow,
.oyss .flood:focus-visible .flood__eyebrow { color: rgba(255, 255, 255, .94); }
.oyss .flood:hover .flood__meta,
.oyss .flood:focus-visible .flood__meta { color: rgba(255, 255, 255, .82); }

@media (max-width: 700px) {
  .oyss .flood__inner { flex-direction: column; align-items: flex-start; }
  .oyss .flood__arrow { margin-top: .2rem; }
}
@media (hover: none), (max-width: 900px) {
  .oyss .flood::before { transform: scaleY(1); }
  .oyss .flood__eyebrow { color: rgba(255, 255, 255, .94); }
  .oyss .flood__meta { color: rgba(255, 255, 255, .82); }
  .oyss .flood__arrow { background: var(--ivory); border-color: var(--ivory); color: #9E1616; }
}


/* ============================================================
   34. THE SPLIT NOTE
   A plain two column statement: what we hand over, what stays
   with you. Borrowed structure from stagingsolutions.com, whose
   copy the client asked this site's copy to read like: short
   label, plain sentence, nothing to decode.
   ============================================================ */

.oyss .plainrow { display: grid; grid-template-columns: 14rem 1fr; gap: clamp(18px, 3vw, 48px);
                  padding: clamp(22px, 2.6vw, 34px) 0; border-top: 1px solid var(--ash); }
.oyss .dark .plainrow, .oyss .stage .plainrow { border-top-color: rgba(228, 218, 214, .16); }
.oyss .plainrow__k { font-size: var(--t-eyebrow); font-weight: 600; letter-spacing: .2em;
                     text-transform: uppercase; color: #B91C1C; padding-top: .28rem; }
.oyss .dark .plainrow__k, .oyss .stage .plainrow__k { color: var(--gold); }
.oyss .plainrow__v { max-width: 46rem; }
.oyss .plainrow__v .caption { margin-top: .5rem; }
@media (max-width: 720px) { .oyss .plainrow { grid-template-columns: 1fr; gap: .5rem; } }

/* ============================================================
   35. THE REEL, ON AN INTERIOR PAGE
   ------------------------------------------------------------
   The home page was rebuilt and the other ten were left opening
   the old way, which made the site read as two sites. They all
   use the same component now: type column left, media panel full
   bleed right, masthead transparent over it.

   What changes is only the size and what is in the panel. The
   home page gets the spotlight footage. Every other page gets a
   COMMISSIONED STILL, one per page rather than one plate reused
   six times, chosen so the picture at the top of a page is about
   that page:

     panel-host   the host frame, lit          apply
     panel-room   four experts in conversation experience, panelist application
     attendee     watching, screen on the face assessment
     desk         a closed notebook and a pen  spotlight call
     clips        the footage afterwards       faq
     room-empty   an empty lit room            about
     texture      a raked dark surface         both agreements

   Two sizes. A guide is something you read, so its head can take
   the room. A form or an agreement is an object you fill in, and
   the object is the content: its head gets out of the way.
   ============================================================ */

.oyss .reel--page  { min-height: clamp(400px, 62svh, 660px); }
.oyss .reel--short { min-height: clamp(330px, 48svh, 540px); }

.oyss .reel--page .display  { font-size: clamp(2.2rem, 1.45rem + 2.7vw, 3.6rem); }
.oyss .reel--short .display { font-size: clamp(1.95rem, 1.4rem + 2.1vw, 3.05rem); }

/* An interior head sits under a bar the reader has already seen,
   so it needs less air above it than the home page does. */
.oyss .reel--page .reel__copy,
.oyss .reel--short .reel__copy {
  padding-top: calc(var(--oyss-mh, 78px) + clamp(22px, 3.6vh, 56px));
  padding-bottom: clamp(32px, 5.5vh, 72px);
}
.oyss .reel--short .reel__rule { margin-top: 1.35rem; }
.oyss .reel--short .lead { margin-top: 1.35rem; }
.oyss .reel--short .actions { margin-top: 1.8rem; }

/* The caption that some heads carry under the lead. */
.oyss .reel .caption { color: var(--ivory-46); margin-top: 1.1rem; max-width: 32rem; }
.oyss .reel .draft-flag { margin-top: 1.5rem; }

/* Plates are stills, and every one of them is now a commissioned photograph
   rather than a frame lifted out of the retired brand film. Each page carries
   the shot that belongs to it, so the framing is per subject, not per class.

   Written against `.reel__media img` and not the plate class alone: the base
   rule that sets the hero clip's framing is .oyss .reel__media img, which
   outranks a bare .oyss .reel__plate and silently wins. That bug has been paid
   for twice on this project.

   On a desktop the panel is near square and these barely bite. Narrow, it
   becomes a wide short slot that cannot hold a whole portrait, so the second
   block re-centers on the one thing each frame still has room for: a face.
   Those rules must sit AFTER these and not merely inside a media query, since
   the selectors are identical and source order is what decides. */
/* Feedback 5.0, note 9: "The image is cutting of the panelist one main
   image. Check and fix all the header image in mobile."

   This list had gone stale. Rounds 8 and 9 replaced almost every hero
   picture and only two of the names below still existed, so six pages were
   falling through to the base `center 58%`, which anchors low and takes the
   top of somebody's head off the moment the panel becomes a wide short slot.
   Every current hero is named here now, and the narrow block under it is
   set from where each subject's head actually sits. */
.oyss .reel__media img[src$="panel-host.jpg"]   { object-position: center 38%; }
.oyss .reel__media img[src$="prep.jpg"]         { object-position: center 40%; }
.oyss .reel__media img[src$="greenroom.jpg"]    { object-position: center 50%; }
.oyss .reel__media img[src$="room-figure.jpg"]  { object-position: center 52%; }
.oyss .reel__media img[src$="reading.jpg"]      { object-position: center 44%; }
.oyss .reel__media img[src$="house.jpg"]        { object-position: center 46%; }
.oyss .reel__media img[src$="talking.jpg"]      { object-position: center 42%; }
.oyss .reel__media img[src$="panelist-mid.jpg"] { object-position: center 38%; }
.oyss .reel__media img[src$="texture.jpg"]      { object-position: center 50%; }

@media (max-width: 1040px) {
  .oyss .reel__media img[src$="panel-host.jpg"]   { object-position: center 24%; }
  .oyss .reel__media img[src$="prep.jpg"]         { object-position: center 10%; }
  .oyss .reel__media img[src$="greenroom.jpg"]    { object-position: center 48%; }
  .oyss .reel__media img[src$="room-figure.jpg"]  { object-position: center 50%; }
  .oyss .reel__media img[src$="reading.jpg"]      { object-position: center 18%; }
  .oyss .reel__media img[src$="house.jpg"]        { object-position: center 34%; }
  .oyss .reel__media img[src$="talking.jpg"]      { object-position: center 28%; }
  .oyss .reel__media img[src$="panelist-mid.jpg"] { object-position: center 8%; }
}

@media (min-width: 1041px) and (max-height: 780px) {
  .oyss .reel--page .display  { font-size: clamp(2rem, 1.35rem + 2.2vw, 3rem); }
  .oyss .reel--short .display { font-size: clamp(1.85rem, 1.3rem + 1.8vw, 2.6rem); }
}

@media (max-width: 1040px) {
  .oyss .reel--page .reel__media  { height: clamp(240px, 34svh, 400px); }
  .oyss .reel--short .reel__media { height: clamp(190px, 26svh, 320px); }
  .oyss .reel--page .reel__copy,
  .oyss .reel--short .reel__copy {
    padding-top: clamp(24px, 4vw, 40px);
    padding-bottom: clamp(38px, 7vw, 64px);
  }
}
@media (max-width: 620px) {
  .oyss .reel--page .reel__media  { height: clamp(200px, 28svh, 300px); }
  .oyss .reel--short .reel__media { height: clamp(160px, 22svh, 240px); }
  .oyss .reel--page .display  { font-size: clamp(1.85rem, 1.3rem + 2.4vw, 2.5rem); }
  .oyss .reel--short .display { font-size: clamp(1.7rem, 1.25rem + 2vw, 2.2rem); }
}


/* ============================================================
   36. THE HUMAN PASS
   ------------------------------------------------------------
   Two reviews arrived together. One said the page looked
   machine-made; the other said it had twelve ideas and no
   spine. They are the same complaint from two directions, and
   the fix is structural rather than cosmetic.

   The tell was never a color or a typeface. It was the RHYTHM:
   every section built from the same kit (kicker, clever
   headline, one supporting line, a grid of equal cards), 01/02/03
   printed in four unrelated places, and a clever line in every
   slot so none of them landed. A human designer gets bored
   around section four and does something else.

   So this section carries the components that are deliberately
   built WRONG for that kit:

     .facts     a line of plain numbers instead of a proof band
     .essay     one offset column of running prose, no grid at all
     .showcase  overlapping plates at unequal widths and baselines
     .manifest  an itemized list with a quantity column, like a
                delivery note rather than a feature grid

   Plus the hero retune for the client's own footage and the
   masthead blend it needs.
   ============================================================ */

/* ---- 36.1 THE HERO, ON THE SPOTLIGHT REVEAL -----------------
   The clip is 1080x1920. A 9:16 frame is the one shape the
   split hero was already the right answer for: the media panel
   is roughly 0.8:1, so cover crops the height by about a third
   and nothing that matters leaves the frame.

   14 September's clip (assets/media/hero-reveal.mp4, built by
   _art/hero_reveal.py) puts the figure lower and taller than
   the erasio cut did: measured, her head is at 35.5% of the
   source height, her feet at 88%, the pool's brightest row at
   81%. The old 58% cut her off at the ankles on a 1536x825
   laptop and at the shins at 1920x1080. 70% keeps head and feet
   in at every desktop size from 1280x720 up: at 1920x1080 the
   visible band is 500..1705 of 1920, and the head sits 64px
   under the masthead's bottom edge. The beam's apex was never
   in the frame, so what the extra top crop costs is haze.
   ------------------------------------------------------------ */

.oyss .reel--spot .reel__media video,
.oyss .reel--spot .reel__media img {
  object-position: 50% 70%;
}
/* The room is darker than --ink at the edges, so the panel needs
   its own ground or the seam shows before the poster arrives. */
.oyss .reel--spot .reel__media { background: #0D0C0C; }

/* The right-hand feather is tighter for this clip than it was
   for the doorway: the beam is centered, so eating 22% of the
   panel width takes the light itself rather than a dark margin. */
.oyss .reel--spot .reel__media::after {
  background:
    linear-gradient(to right,
      var(--ink) 0%, rgba(19, 18, 17, .80) 5%, rgba(19, 18, 17, .26) 16%, rgba(19, 18, 17, 0) 34%),
    linear-gradient(to bottom,
      rgba(19, 18, 17, 0) 62%, rgba(19, 18, 17, .42) 88%, rgba(19, 18, 17, .78) 100%);
}

/* ---- 36.2 THE MASTHEAD BLEND --------------------------------
   The bar is transparent over the hero, which was fine over a
   dark doorway and is not fine over a beam: the cone is the
   brightest thing in the frame and it arrives exactly where the
   navigation sits.

   A text-shadow was doing that job. A shadow behind ivory type
   is a crutch, and it still leaves the bar looking stuck ON the
   picture. This is a real scrim instead, in Authority Navy
   rather than ink, so the bar dissolves into the top of the
   room and the beam appears to come from behind it. It spans
   the whole hero, not just the media panel, so the two columns
   share one ceiling.

   It goes on EVERY hero, not only the home page. Measuring real
   pixels behind the bar rather than walking DOM colors turned
   up the same failure on four interior pages, against the light
   in the plates: "FAQ" at 3.8:1 and the Apply button at 3.6:1
   on apply.html, where a color walk had reported the page
   background and seen nothing wrong.
   ------------------------------------------------------------ */

.oyss .reel[data-over]::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 0;
  height: clamp(150px, 26vh, 260px);
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(180deg,
    rgba(31, 30, 29, .94) 0%,
    rgba(31, 30, 29, .78) 22%,
    rgba(21, 20, 19, .44) 52%,
    rgba(10, 16, 31, .16) 78%,
    rgba(19, 18, 17, 0) 100%);
}
/* Copy sits above the scrim; the media panel sits under it. */
.oyss .reel[data-over] .reel__copy { z-index: 2; }

/* Below 1040px the bar takes its own ground back and the panel
   starts underneath it, so a scrim there is a dark band for no
   reason, on top of the one the panel already draws. */
@media (max-width: 1040px) {
  .oyss .reel[data-over]::before { display: none; }
}

/* With a scrim doing the work the shadow goes back to being a
   whisper, which is what keeps the type looking set rather than
   pasted on. */
.oyss .masthead--over .lockup,
.oyss .masthead--over nav a { text-shadow: 0 1px 10px rgba(13, 12, 12, .55); }

/* ---- 36.3 THE FACTS -----------------------------------------
   The proof line the review asked for, as one line of plain
   numbers rather than a band of three tiles. The numbers are
   the only thing on this page that could not be written by
   something with no access to the business.
   ------------------------------------------------------------ */

.oyss .facts {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .55rem 1.05rem;
  margin-top: 2.4rem;
  padding-top: 1.5rem;
  border-top: 1px solid rgba(228, 218, 214, .18);
  font-size: var(--t-caption);
  letter-spacing: .06em;
  color: rgba(248, 245, 242, .72);
}
.oyss .facts b {
  font-weight: 600;
  color: var(--ivory);
  letter-spacing: .02em;
}
.oyss .facts span { display: inline-flex; align-items: baseline; gap: .45rem; }
.oyss .facts span + span::before {
  content: '';
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--gold);
  transform: translateY(-.25em);
  margin-right: .6rem;
  flex: none;
}

/* ---- 36.4 THE ESSAY -----------------------------------------
   The structural break. No eyebrow, no headline in the section
   ladder, no grid, no picture, no cards, nothing to hover. One
   column of running prose set off-center, with the opening
   sentence at display size and the rest at reading size.

   It is deliberately the quietest thing on the site. A page
   where every section shouts equally is a page with no
   hierarchy, and that flatness is most of what reads as
   generated.
   ------------------------------------------------------------ */

.oyss .essay { background: var(--white); padding: clamp(88px, 12vw, 168px) 0; }
.oyss .essay__inner {
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 var(--gutter);
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(28px, 5vw, 76px);
}
.oyss .essay__body { grid-column: 1; max-width: 40rem; }
.oyss .essay__open {
  font-family: var(--serif); font-weight: 700;
  font-size: clamp(1.85rem, 1.25rem + 2.1vw, 2.9rem);
  line-height: 1.13;
  letter-spacing: -.014em;
  color: var(--navy);
  text-wrap: balance;
}
.oyss .essay__body p + p { margin-top: 1.45rem; }
.oyss .essay__body .p {
  font-size: 1.0625rem;
  line-height: 1.72;
  color: var(--slate);
}
.oyss .essay__body .p em { font-style: normal; color: var(--navy); }
/* The right column holds one short line, low, so the block is
   weighted left and the page stops being symmetrical for a
   screen. */
.oyss .essay__note {
  grid-column: 2;
  align-self: end;
  padding-bottom: .4rem;
  border-left: 2px solid var(--gold);
  padding-left: clamp(16px, 1.6vw, 24px);
  font-size: var(--t-caption);
  line-height: 1.6;
  color: var(--slate);
  max-width: 22rem;
}
@media (max-width: 900px) {
  .oyss .essay__inner { grid-template-columns: 1fr; }
  .oyss .essay__note { grid-column: 1; margin-top: 2.4rem; align-self: start; }
}

/* ---- 36.5 THE SHOWCASE --------------------------------------
   The evidence. A studio that sells production has to show
   production, and the only produced artefacts that exist yet
   are the branded stage frames, which no visitor had ever seen.

   Composed as plates rather than cards: unequal widths, unequal
   baselines, one of them running off the left edge of the page,
   the second hanging lower than the first. Nothing here is a
   grid of three, and that is the point.
   ------------------------------------------------------------ */

.oyss .showcase { position: relative; overflow: hidden; }
.oyss .showcase__lead { max-width: 40rem; }

.oyss .showcase__set {
  margin-top: clamp(38px, 5vw, 66px);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: start;
  column-gap: clamp(24px, 3.4vw, 54px);
}

.oyss .plate {
  position: relative;
  border: 1px solid rgba(228, 218, 214, .18);
  background: #0F0E0E;
  overflow: hidden;
}
.oyss .plate img { width: 100%; height: auto; }
.oyss .plate figcaption {
  padding: .95rem 1.1rem 1.05rem;
  border-top: 1px solid rgba(228, 218, 214, .13);
  font-size: var(--t-caption);
  line-height: 1.5;
  color: var(--ivory-46);
}
.oyss .plate figcaption b {
  display: block;
  font-weight: 600;
  font-size: var(--t-eyebrow);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: .4rem;
}

/* The big one runs off the left edge of the viewport. The same
   expression .reel__copy uses for its left padding, negated: the
   wrap is capped at 1180 and centered, so the distance from the
   viewport edge to the content edge is (100vw - 1180) / 2 plus
   the gutter, and anything less than that leaves the plate
   sitting in a margin looking like it missed. */
.oyss .plate--wide {
  grid-column: 1;
  margin-left: calc(-1 * max(var(--gutter), (100vw - var(--wrap)) / 2 + var(--gutter)));
  border-left: 0;
}
.oyss .plate--wide figcaption {
  padding-left: max(1.1rem, calc(max(var(--gutter), (100vw - var(--wrap)) / 2 + var(--gutter))));
}
.oyss .plate--tall {
  grid-column: 2;
  margin-top: clamp(40px, 7vw, 110px);
  max-width: 30rem;
}
.oyss .showcase__aside {
  grid-column: 2;
  margin-top: clamp(22px, 3vw, 40px);
  max-width: 30rem;
}

@media (max-width: 860px) {
  .oyss .showcase__set { grid-template-columns: 1fr; row-gap: clamp(26px, 5vw, 40px); }
  .oyss .plate--wide { grid-column: 1; margin-left: calc(-1 * var(--gutter)); }
  .oyss .plate--tall, .oyss .showcase__aside { grid-column: 1; margin-top: 0; max-width: none; }
}

/* ---- 36.6 THE MANIFEST --------------------------------------
   The strongest concrete thing in the whole offer, and it was
   nowhere on the site: the content package has real quantities
   attached to it. Three host highlight videos. One per panelist.
   About twenty short-form cuts. A ninety day calendar.

   Set as a delivery note, not a feature grid: a quantity column,
   an item column, hairline rules, no boxes and no icons. It
   reads as something a production company would actually hand
   over, which is the whole argument.
   ------------------------------------------------------------ */

.oyss .manifest { margin-top: clamp(34px, 4vw, 52px); max-width: 62rem; border-top: 1px solid rgba(31, 30, 29, .16); }
.oyss .manifest__row {
  display: grid;
  grid-template-columns: 5.5rem minmax(0, 1fr);
  gap: clamp(14px, 2vw, 30px);
  align-items: baseline;
  padding: 1.15rem 0;
  border-bottom: 1px solid rgba(31, 30, 29, .11);
}
.oyss .manifest__n {
  font-family: var(--serif); font-weight: 700;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--navy);
  letter-spacing: -.01em;
}
.oyss .manifest__n small {
  display: block;
  font-family: var(--sans);
  font-size: var(--t-eyebrow);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #B91C1C;
  margin-top: .4rem;
}
.oyss .manifest__item { color: var(--navy); }
.oyss .manifest__item span {
  display: block;
  font-size: var(--t-caption);
  line-height: 1.55;
  color: var(--slate);
  margin-top: .28rem;
}
.oyss .manifest__foot {
  display: flex; flex-wrap: wrap; gap: .5rem 1.4rem; max-width: 62rem;
  margin-top: 1.5rem;
  font-size: var(--t-caption);
  color: var(--slate);
}
.oyss .manifest__foot b { color: var(--navy); font-weight: 600; }

@media (max-width: 560px) {
  .oyss .manifest__row { grid-template-columns: 4.2rem minmax(0, 1fr); }
  .oyss .manifest__n { font-size: 1.3rem; }
}

/* ---- 36.7 THE TERMS -----------------------------------------
   The honest half of the offer, kept next to the price where a
   real studio puts it, instead of occupying a section of its
   own halfway up the page.
   ------------------------------------------------------------ */

.oyss .terms {
  margin-top: clamp(30px, 3.6vw, 46px);
  padding-top: clamp(24px, 3vw, 34px);
  border-top: 1px solid rgba(31, 30, 29, .16);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(24px, 3.4vw, 52px);
}
.oyss .terms h3 {
  font-size: var(--t-eyebrow);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: #B91C1C;
  margin-bottom: .85rem;
}
.oyss .terms p { font-size: .96875rem; line-height: 1.66; color: var(--slate); }
@media (max-width: 720px) { .oyss .terms { grid-template-columns: 1fr; } }

/* ---- 36.8 THE BYLINE ----------------------------------------
   Annette on the home page, not only on About. A new company
   with no client list has one piece of proof that it is run by
   a person, and that is the person.
   ------------------------------------------------------------ */

.oyss .byline {
  display: grid;
  grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
  gap: clamp(28px, 4.4vw, 68px);
  align-items: center;
}
.oyss .byline .portrait { max-width: 320px; }
.oyss .byline__quote {
  font-family: var(--serif); font-weight: 700;
  font-size: clamp(1.35rem, 1.05rem + 1.25vw, 1.95rem);
  line-height: 1.28;
  letter-spacing: -.01em;
  color: var(--navy);
  text-wrap: pretty;
}
.oyss .byline__attrib {
  margin-top: 1.4rem;
  font-size: var(--t-caption);
  letter-spacing: .04em;
  color: var(--slate);
}
.oyss .byline__attrib b { color: var(--navy); font-weight: 600; }
@media (max-width: 780px) {
  .oyss .byline { grid-template-columns: 1fr; }
  .oyss .byline .portrait { max-width: 260px; }
}

/* ---- 36.9 THE SIDE DOOR, AS ONE LINE ------------------------
   The panelist route used to be a full section with the same
   visual weight as the flagship, on a page where the two offers
   are $2,997 and $47. Every host read the cheap number and every
   panelist bounced off the expensive one. It is one line now,
   near the end, pointing at its own page.
   ------------------------------------------------------------ */

.oyss .sidedoor {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .6rem 1.1rem;
  padding: 1.2rem 0 0;
  font-size: .96875rem;
  color: rgba(248, 245, 242, .74);
}
.oyss .sidedoor a {
  border-bottom: 1px solid var(--gold-40);
  padding-bottom: .15rem;
  color: var(--ivory);
  transition: border-color 220ms var(--settle);
}
.oyss .sidedoor a:hover { border-color: var(--gold); }

/* ---- 36.10 THE CLOSING PLATE --------------------------------
   The last section was pure CSS light: a measured cone of conic
   gradients with a rAF ignition. It is a good piece of work and
   it is still on the About page, but on a page whose brief is
   "show the real thing" the last image should be a photograph.

   So the close now stands on a frame from the client's own clip,
   at the moment the stage is lit and nobody is in it yet. The
   CSS lamp is removed from this one section rather than layered
   under it: two beams at different angles is two lamps, and the
   deck allows one.

   The plate is cropped to roughly the aspect the section renders
   at, so `cover` barely crops and the pool stays where it was
   composed. The scrim over it is what the type reads against.
   ------------------------------------------------------------ */

.oyss .stage--plate::before {
  content: '';
  position: absolute; inset: 0;
  background-image: url('media/plate-stage.jpg');
  background-size: cover;
  background-position: 50% 8%;
  z-index: 0;
  pointer-events: none;
}
/* The room is real, so the legibility has to be built rather than
   assumed: navy at the top where the headline sits, opening up
   over the pool, closing again into the flood. */
.oyss .stage--plate::after {
  content: '';
  position: absolute; inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    linear-gradient(180deg,
      rgba(19, 18, 17, .74) 0%, rgba(19, 18, 17, .52) 30%,
      rgba(19, 18, 17, .48) 56%, rgba(19, 18, 17, .70) 82%, rgba(19, 18, 17, .88) 100%),
    linear-gradient(90deg,
      rgba(19, 18, 17, .46) 0%, rgba(19, 18, 17, 0) 28%,
      rgba(19, 18, 17, 0) 72%, rgba(19, 18, 17, .46) 100%);
}
.oyss .stage--plate > * { position: relative; z-index: 1; }
/* the pool the section draws itself would be a second one */
.oyss .stage--plate .stage__pool { display: none; }

/* ---- 36.11 THE RIG, ON THE REAL ARTWORK ---------------------
   The rig used to draw its own frames with a CSS gradient, which
   is a diagram of the product rather than the product. The
   backdrop is now a crop of the studio's actual panelist frame,
   taken from between the badge and the baked nameplate so the
   six frames can carry live names instead of the same "Your Name
   Here" printed six times.

   Nameplates sit bottom right here, because that is where they
   sit on the real frames.
   ------------------------------------------------------------ */

.oyss .rig--art .frame {
  background-image: url('media/rig-frame.jpg');
  background-size: cover;
  background-position: 50% 42%;
  justify-content: flex-end;
}
.oyss .rig--art .frame__plate {
  border-left: 0;
  border-right: 2px solid var(--gold);
  text-align: right;
  background: rgba(19, 18, 17, .62);
}
/* The host frame is twice the size, so it carries the warmer key
   the host frame actually has rather than the panelist navy. */
.oyss .rig--art .frame--host { background-position: 50% 46%; }
.oyss .rig--art .frame--host::after {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(58% 78% at 50% 0%, rgba(224, 90, 90, .16) 0%, transparent 70%);
  pointer-events: none;
}
/* The note now runs to two lines, so the gold dash has to hang
   at the first line rather than center against the whole block. */
.oyss .rig__note { align-items: flex-start; line-height: 1.6; max-width: 46rem; }
.oyss .rig__note::before { margin-top: .58em; }

/* ---- 36.12 CORRECTIONS THE NEW SECTIONS NEED ----------------
   Small things that only show up once the page is built.
   ------------------------------------------------------------ */

/* .paper is --white, and the manifest rules were drawn for it.
   The section above the manifest is dark, so the seam needs the
   rules to start under the heading rather than at the section
   edge. Handled in markup; this is only the top rule weight. */
.oyss .manifest { border-top-color: rgba(31, 30, 29, .22); }

/* The showcase heading column sits against a plate that bleeds
   left, so it must not run the full 1180px or the two collide
   on a mid-width screen. */


/* The closing section holds a photographic plate, the CSS spot
   and the flood. The flood has to sit above the plate or the
   crimson wash comes up behind a photograph. */
.oyss .stage--plate .flood { position: relative; z-index: 2; }

/* ---- 36.13 THE CREED ----------------------------------------
   The five brand words used to be a numbered cue stack on a
   rail, 01 to 05. The order of the five is not the content, so
   the numbers were decoration, and a rail is the third place on
   the site drawing the same picture. One paragraph, with the
   words themselves stepped up into the serif.
   ------------------------------------------------------------ */

.oyss .creed {
  margin-top: 1.7rem;
  font-size: var(--t-lead);
  line-height: 1.62;
  font-weight: 300;
  color: var(--slate);
  max-width: 46rem;
}
.oyss .creed b {
  font-family: var(--serif);
  font-weight: 700;
  font-size: 1.16em;
  letter-spacing: -.005em;
  color: var(--navy);
}
.oyss .dark .creed, .oyss .stage .creed { color: var(--ivory-70); }
.oyss .dark .creed b, .oyss .stage .creed b { color: var(--ivory); }

/* ---- 36.14 THE DRAFT FLAG ON A DARK HERO --------------------
   Measured, not guessed: #B91C1C is the darkest gold that passes
   on ivory, and it is 3.31:1 on the near-black hero the two
   agreements now open with. On a dark ground the flag takes the
   full Spotlight Gold, which measures 8.8:1 there.
   ------------------------------------------------------------ */
.oyss .dark .draft-flag, .oyss .stage .draft-flag {
  color: var(--gold);
  background: rgba(224, 90, 90, .10);
  border-color: rgba(224, 90, 90, .46);
}

/* ---- 36.15 THE HOME HERO ON A LANDSCAPE TABLET --------------
   Every other hero on the site can stack below 1040px, because a
   plate cut from the film is landscape and a short wide panel is
   the shape it was cut for.

   The home hero cannot. Its clip is 1080x1920. Stack it at
   1024x768 and the panel becomes 1024 wide by 400 tall, which
   with `cover` shows 12% of the frame height: a horizontal band
   across the subject's chest, no beam, no pool, no floor. The
   primary action also lands at y=938 on a 768px viewport, which
   is a hero with its button off the screen.

   So this one keeps the split down to 861px, the same width the
   rest of the site drops its two-column layouts at. Below that
   it stacks like the others, and by then the viewport is narrow
   enough that a full-width panel is portrait-ish again.
   ------------------------------------------------------------ */

@media (min-width: 861px) and (max-width: 1040px) {
  .oyss .reel--spot {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    align-items: center;
    min-height: clamp(520px, 100svh, 940px);
    margin-top: calc(-1 * var(--oyss-mh, 78px));
  }
  .oyss .reel--spot .reel__media {
    order: 0;
    height: auto;
    align-self: stretch;
  }
  /* the desktop feather, not the stacked one */
  .oyss .reel--spot .reel__media::after {
    background:
      linear-gradient(to right,
        var(--ink) 0%, rgba(19, 18, 17, .80) 5%, rgba(19, 18, 17, .26) 16%, rgba(19, 18, 17, 0) 34%),
      linear-gradient(to bottom,
        rgba(19, 18, 17, 0) 62%, rgba(19, 18, 17, .42) 88%, rgba(19, 18, 17, .78) 100%);
  }
  .oyss .reel--spot .reel__copy {
    justify-self: end;
    margin: 0;
    max-width: 32rem;
    padding: calc(var(--oyss-mh, 78px) + clamp(18px, 3vh, 40px)) clamp(22px, 2.6vw, 36px)
             clamp(28px, 5vh, 56px) var(--gutter);
  }
  /* 429px of measure will not hold a 55px headline. */
  .oyss .reel--spot .display { font-size: clamp(1.95rem, 1.1rem + 2.4vw, 2.75rem); }
  .oyss .reel--spot .eyebrow--keyed { margin-bottom: 1.05rem; }
  .oyss .reel--spot .reel__rule { margin-top: 1.25rem; }
  .oyss .reel--spot .lead { margin-top: 1.25rem; font-size: 1.0625rem; }
  .oyss .reel--spot .actions { margin-top: 1.7rem; }
  .oyss .reel--spot .facts { margin-top: 1.6rem; padding-top: 1.1rem; }
  /* The bar has the film under it again here, so it gives its
     ground back. Scoped with :has() because the masthead is a
     sibling of main, and this must not reach the ten interior
     pages, whose heroes really do stack at this width. Without
     :has() support the bar simply keeps its navy, which is the
     behavior that shipped before this rule. */
  .oyss:has(.reel--spot) .masthead--over {
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border-bottom-color: transparent;
  }
  /* has to out-specify .reel[data-over]::before { display:none } */
  .oyss .reel--spot[data-over]::before { display: block; }
}

/* Below 861 the home hero stacks, and the panel is sized by two
   numbers that fight: tall enough that a 9:16 frame still reads
   as a room, short enough that the primary action is not pushed
   off the bottom of the screen. Measured at 390x844, where the
   button now clears the fold by about 50px. */
@media (max-width: 860px) {
  .oyss .reel--spot .reel__media { height: clamp(260px, 34svh, 420px); }
  /* Stacked, the panel is a wide short band and cover is width
     constrained, so on a 390x844 phone it shows 748 of the source's
     1920 rows and on a 768x1024 tablet 489. Anything above about 50%
     starts at or below the head (y 682). 40% opens the band at 469
     on the phone, 407 on the tablet, 557 on an 820x1180 iPad Air and
     635 on a phone turned sideways: the head with room over it, then
     as much of her as the band can hold. The feet are the price at
     this width, not the head. Measured with Playwright at all five. */
  .oyss .reel--spot .reel__media video,
  .oyss .reel--spot .reel__media img { object-position: 50% 40%; }
}
@media (max-width: 620px) {
  .oyss .reel--spot .reel__media { height: clamp(250px, 32svh, 360px); }
}


/* ============================================================
   37. THE BRAND DECK PASS
   ------------------------------------------------------------
   A second reader went back to OYSS_Brand_Deck_v3 and said the
   site had drifted from it. They were right on five counts, and
   every one is a sentence in the deck rather than a matter of
   taste. Each fix below cites its page.
   ============================================================ */

/* ---- 37.1 THE MARK IS A COMPLETE CIRCLE (deck p17, p19) -----
   "The icon is always a complete circle or a complete square. It
   is never bled off an edge or half shown." There are five
   approved colorways and a bare beam is not one of them.

   The disc was dropped in an earlier pass because a navy circle
   on a navy bar is invisible. The deck's own website mock, page
   24, answers that by flipping the colorway rather than
   deleting the shape. The mark that replaced it has no disc to
   delete: it is the A itself, so it survives being reversed by
   changing one fill. Both colorways live in section 7 with the
   rest of the lockup, and this section now only owns where the
   strike starts.
   ------------------------------------------------------------ */

@media (prefers-reduced-motion: no-preference) {
  /* The A rises off its own feet; the arch blooms from its base. */
  .oyss .lockup--motion .mark__a    { transform-origin: 32px 58px; }
  .oyss .lockup--motion .mark__arch { transform-origin: 32px 46px; }
}

/* ---- 37.2 THE EYEBROW IS CRIMSON ON LIGHT (deck p11) --------
   The type hierarchy page sets the eyebrow in Stage Crimson on
   ivory and in Spotlight Gold on navy, and it is captioned
   "Six levels, and no more. Every page in every medium is built
   from this ladder." The site had slate on light, which is the
   one level of the ladder that was not being followed.

   #B91C1C on #F8F5F2 measures 5.19:1, so this is also the
   accessible choice, not a trade against it.
   ------------------------------------------------------------ */

.oyss .eyebrow { color: var(--crimson); }
.oyss .dark .eyebrow, .oyss .stage .eyebrow { color: var(--gold); }
/* .eyebrow--gold survives for the places gold is carrying a
   quantity rather than labelling a section. */

/* ---- 37.3 THE RULE IS THE ONLY ORNAMENT --------------------
   The old deck allowed exactly one ornament, a flat gold pool,
   and this rule was drawn as one. The brand sheet allows exactly
   one too and it is a short red rule: it sits under BOLDER
   VOICES on one board and under REAL EXPERTISE on the other, and
   there is no pool on either. Same discipline, different shape.
   ------------------------------------------------------------ */

.oyss .reel__rule {
  width: 74px; height: 3px;
  border-radius: 2px;
  background: var(--rose);
}

/* ---- 37.4 THE GOLD FIELD (deck p13, p19) --------------------
   "SPOTLIGHT HIGHLIGHT. Rare. A single panel, a pull quote, a
   moment of emphasis." It is an approved surface in the palette
   and it appeared nowhere on the site. One panel, once, on the
   founder's quotation, which is the only moment on the page that
   is a pull quote.

   Navy on gold measures 8.9:1. On this field the lockup, the
   rules and the type all go navy: "Everything navy, including
   the pool." (p19)
   ------------------------------------------------------------ */

.oyss .goldfield {
  background: var(--blush);
  color: var(--navy);
}
.oyss .goldfield .eyebrow { color: var(--red); }
.oyss .goldfield .byline__quote,
.oyss .goldfield .byline__attrib b,
.oyss .goldfield h2 { color: var(--navy); }
.oyss .goldfield .byline__attrib,
.oyss .goldfield .body,
.oyss .goldfield .caption { color: #6A5F5C; }
.oyss .goldfield .cue { border-bottom-color: rgba(31, 30, 29, .34); color: var(--navy); }
.oyss .goldfield .cue:hover { border-bottom-color: var(--red); color: var(--red); }
.oyss .goldfield .portrait { border-color: rgba(31, 30, 29, .18); }
/* The pull quote closes on a Signature Red rule rather than the old pool:
   on Soft Blush the pool was the same family as its own ground. */
.oyss .goldfield .byline__quote::after {
  content: '';
  display: block;
  width: 64px; height: 3px;
  border-radius: 2px;
  background: var(--red);
  margin-top: 1.5rem;
}

/* ---- 37.5 THE TAGLINE IS SET, NOT TYPED (deck p25) ----------
   The signature line closes the deck in gold italic serif with
   the pool under it. In the footer it was plain sans.
   ------------------------------------------------------------ */

.oyss .footer__promise {
  font-family: var(--script); font-weight: 400;
  font-size: 2.05rem;
  line-height: 1.12;
  color: var(--rose);
  margin-top: 1.15rem;
}
.oyss .footer__promise::after {
  content: '';
  display: block;
  width: 58px; height: 3px;
  border-radius: 2px;
  background: var(--rose);
  margin-top: .95rem;
}


/* ============================================================
   38. THE STAGE, WITH PEOPLE IN IT
   ------------------------------------------------------------
   The note that came back was that the third section looked
   flat and cheap. It did, and deck page 22 says why in one
   sentence:

     "The center two thirds of the frame stays empty. That is
      where the person sits, and it is the only reason this
      background exists."

   The site was showing those frames empty. An empty backdrop is
   not the product, it is the thing the product happens in front
   of, and at 700px wide it reads as a flat gradient with a
   banded edge, because that is exactly what it is.

   So the frames now hold people, shot to the specification on
   deck page 21, which does not describe a mood but hands over a
   six item list "to commission or license":

     01 host portrait, shoulders up, warm key, navy background
     02 panel of four in conversation, mid shot, no podium
     03 attendee watching intently, screen light on the face
     04 empty lit room, negative space for headline overlay
     05 hands and notebook, shallow depth, warm desk lamp
     06 texture plate, dark surface with a single light shaft

   None of the six existed. They do now, commissioned against
   that brief. The brand furniture over the top stays live text
   and vector, so nameplates edit in seconds and stay crisp:
   photography does the photography, code does the code.
   ============================================================ */

/* ---- 38.1 THE BAND -----------------------------------------
   A full bleed piece of footage with the section's own words
   over it. The scrim is built rather than hoped for: navy at
   60 percent minimum wherever type or the mark sits, which is
   the floor deck page 19 sets for anything over an image.
   ------------------------------------------------------------ */

.oyss .band {
  position: relative;
  overflow: hidden;
  background: var(--ink);
  display: grid;
  align-items: end;
  min-height: clamp(380px, 58svh, 620px);
}
.oyss .band__media { position: absolute; inset: 0; }
.oyss .band__media video,
.oyss .band__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 46%;
}
.oyss .band__media::after {
  content: '';
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg,
      rgba(19, 18, 17, .46) 0%, rgba(19, 18, 17, .06) 30%,
      rgba(19, 18, 17, .28) 70%, rgba(19, 18, 17, .82) 100%),
    linear-gradient(90deg,
      rgba(19, 18, 17, .80) 0%, rgba(19, 18, 17, .58) 26%,
      rgba(19, 18, 17, .10) 52%, rgba(19, 18, 17, 0) 66%);
}
.oyss .band__copy {
  position: relative;
  z-index: 1;
  /* padding-block, NOT the shorthand. `.band__copy` is also a `.wrap`, and a
     four value shorthand here set the left and right to 0 and took the wrap's
     gutter with it. On a desktop the wrap is capped at 1180 and centered, so
     there was room either side anyway and nothing showed. On a phone the wrap
     is the full width and the gutter IS the padding, so the headline started
     at x=0 and ran off the right edge. Feedback 5.0, notes 6 and 8: "The text
     is cutting on mobile" and "The text is very sticking to the screen". */
  padding-block: clamp(56px, 9vw, 110px) clamp(38px, 5.5vw, 66px);
}
.oyss .band__copy .lead { color: rgba(248, 245, 242, .86); }
.oyss .band--tall { min-height: clamp(440px, 72svh, 760px); }

/* Under 760px the band clips do not load at all: the poster is the same frame,
   the copy is what the section is for, and 730KB of ambient footage is not a
   thing to spend a phone's data on to move some haze behind a headline. The
   markup keeps preload="none" so nothing is fetched before this decides. */
@media (max-width: 760px) {
  .oyss .band__media video { display: none; }
  /* the poster goes on the media box itself, which sits UNDER its own ::after
     scrim, so the type keeps the ground it was measured against */
  .oyss .band__media { background-size: cover; background-position: 50% 46%; }
  .oyss .band--build .band__media { background-image: url('media/stage-build-poster.jpg'); }
  .oyss .band--drift .band__media { background-image: url('media/panel-drift-poster.jpg'); }
}

/* ---- 38.2 THE RIG, WITH PEOPLE ------------------------------
   Same six frame grid and the same producer switching between
   them, but each frame now carries a photograph instead of a
   gradient, and the brand furniture is dressed to deck page 22:

     host frame       horizontal lockup top left, name plate
                      bottom right, red stage lip along the floor
     panelist frame   icon only, lighter navy, smaller plate
     the key light    moves to whoever is speaking

   Everything except the photograph is live: change a name and
   it is changed, at any resolution.
   ------------------------------------------------------------ */

.oyss .rig--live .frame {
  background: #161514;
  padding: 0;
  display: block;
  border-color: rgba(228, 218, 214, .10);
}
.oyss .rig--live .frame img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 34%;
  /* Unlit is not hidden: a panel where five faces are invisible
     is not a panel. It is the light that moves, not the people. */
  filter: brightness(.52) saturate(.72);
  transition: filter 620ms var(--settle);
}
.oyss .rig--live .frame.on img { filter: brightness(1) saturate(1); }

/* the key, over the photograph rather than under it */
.oyss .rig--live .frame::before {
  top: -52%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(255, 222, 216, .20) 0%, transparent 62%);
  mix-blend-mode: screen;
}

/* the stage lip: the red rule along the floor of every frame */
.oyss .rig--live .frame::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px;
  background: linear-gradient(90deg,
    rgba(224, 90, 90, 0) 0%, rgba(224, 90, 90, .70) 22%,
    rgba(224, 90, 90, .70) 78%, rgba(224, 90, 90, 0) 100%);
  opacity: .45;
  transition: opacity 620ms var(--settle);
}
.oyss .rig--live .frame.on::after { opacity: 1; }

/* the name plate, bottom right, the way the real frames set it */
.oyss .rig--live .frame__plate {
  position: absolute;
  right: 0; bottom: 0;
  max-width: 84%;
  padding: .55rem .8rem .7rem 1rem;
  text-align: right;
  background: linear-gradient(270deg, rgba(19, 18, 17, .88) 0%, rgba(19, 18, 17, .78) 62%, rgba(19, 18, 17, 0) 100%);
  border: 0;
  backdrop-filter: none;
}
.oyss .rig--live .frame__role { color: rgba(248, 245, 242, .62); letter-spacing: .3em; }
.oyss .rig--live .frame--host .frame__role { color: var(--gold); }
.oyss .rig--live .frame__sub { color: var(--gold); font-size: .6875rem; }

/* the mark, per the deck: full lockup on the host, icon only on a panelist */
.oyss .rig--live .frame__mark {
  position: absolute; left: 12px; top: 11px;
  display: flex; align-items: center; gap: .5rem;
  z-index: 2;
}
.oyss .rig--live .frame__mark svg { width: 22px; height: 22px; flex: none; }
.oyss .rig--live .frame__mark b {
  font-family: var(--serif); font-weight: 700;
  font-size: .66rem; letter-spacing: .17em; text-transform: uppercase;
  color: var(--ivory); line-height: 1;
}
.oyss .rig--live .frame:not(.frame--host) .frame__mark b { display: none; }
.oyss .rig--live .frame:not(.frame--host) .frame__mark svg { width: 17px; height: 17px; }

.oyss .rig--live .frame__live {
  left: auto; right: 12px; top: 11px;
  z-index: 2;
}

@media (max-width: 760px) {
  .oyss .rig--live .frame__mark { left: 9px; top: 8px; }
  .oyss .rig--live .frame__plate { padding: .4rem .6rem .5rem .8rem; }
}

/* ---- 38.3 THE ESSAY GETS A FACE -----------------------------
   The problem section was deliberately imageless, on the theory
   that a page of pure prose is the strongest possible break from
   a grid of cards. It is, and it also spent the reader's second
   screen on nothing. The prose keeps the left, off center, and a
   portrait takes the right at full height. Still no grid, still
   no card, and now a person.
   ------------------------------------------------------------ */

.oyss .essay--faced .essay__inner {
  grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
  align-items: start;
  gap: clamp(28px, 5vw, 84px);
}
.oyss .essay__portrait {
  grid-column: 2;
  grid-row: 1 / span 2;
  position: relative;
  align-self: stretch;
  min-height: clamp(340px, 44vw, 560px);
  overflow: hidden;
  background: var(--navy);
}
.oyss .essay__portrait img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 22%;
}
/* Warm White is what lifts things off Ivory (deck p12), so the
   plate sits on the picture rather than around it. */
.oyss .essay__portrait::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(19, 18, 17, 0) 58%, rgba(19, 18, 17, .34) 100%);
}
.oyss .essay--faced .essay__note {
  grid-column: 1;
  grid-row: 2;
  align-self: start;
  margin-top: 2.6rem;
  max-width: 30rem;
}
@media (max-width: 900px) {
  .oyss .essay--faced .essay__inner { grid-template-columns: 1fr; }
  .oyss .essay__portrait {
    grid-column: 1; grid-row: 2;
    min-height: 0; aspect-ratio: 5 / 4;
    margin-top: 2.4rem;
  }
  .oyss .essay--faced .essay__note { grid-row: 3; }
}

/* ---- 38.4 A PLATE THAT IS A PICTURE, NOT A DIAGRAM ----------
   The remaining two commissioned shots carry the sections they
   belong to: hands and notebook for the stage where the strategy
   is set, the attendee for the one about what keeps working
   after the room closes.
   ------------------------------------------------------------ */

.oyss .figure-wide {
  position: relative;
  margin-top: clamp(34px, 4.5vw, 60px);
  border: 1px solid rgba(31, 30, 29, .14);
  overflow: hidden;
  background: var(--navy);
}
.oyss .dark .figure-wide, .oyss .stage .figure-wide { border-color: rgba(228, 218, 214, .16); }
.oyss .figure-wide img { width: 100%; height: auto; display: block; }
.oyss .figure-wide figcaption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 1.6rem clamp(18px, 2.4vw, 32px) 1.15rem;
  background: linear-gradient(180deg, rgba(19, 18, 17, 0) 0%, rgba(19, 18, 17, .82) 62%);
  color: rgba(248, 245, 242, .82);
  font-size: var(--t-caption);
  line-height: 1.5;
}

/* The founder plate sits on a photograph inside the gold field, so it keeps
   its own dark-context colors. Without this the label goes brown on black. */
.oyss .goldfield .portrait__plate .eyebrow { color: var(--gold); }
.oyss .goldfield .portrait__plate .name { color: var(--ivory); }

/* ---- 38.5 THE SHEET WAS EATING THE HERO ---------------------
   Pre-existing, and only visible once the plates behind these
   heroes became photographs with something in them. The sheet
   lifts out of the dark hero with a negative top margin of up to
   84px, and `.reel--short` sizes itself on min-height, not on
   its content. On apply.html the lead runs to three lines and
   the last of them was 40px UNDER the sheet: the sentence "This
   application tells us whether the timing is right" simply was
   not on the page at 1366 or 1440.

   Nothing was overflowing and no contrast test could see it,
   because the text was present, painted, and covered. Measured
   with getBoundingClientRect on the lead against the sheet.

   The fix is padding on the hero rather than a smaller lift: the
   lift is the component's whole idea, so the hero has to leave
   room for it instead of the sheet giving it up.
   ------------------------------------------------------------ */

.oyss .reel--short .reel__copy { padding-bottom: clamp(70px, 11vh, 132px); }

/* .reel--short's min-height clamp bottoms out at 48svh, and on a 768px tall
   viewport that is 369px: shorter than the copy column now needs, so the copy
   sets the height and the padding is what has to absorb the lift. Verified
   across the four form pages at five widths, worst case 0px. */
@media (max-height: 820px) {
  .oyss .reel--short .reel__copy { padding-bottom: clamp(80px, 13vh, 140px); }
}


/* ============================================================
   39. READING SIZE
   ------------------------------------------------------------
   "make para text bigger because the audience is going to be old
   coaches or established personalities."

   That is the whole brief and it is correct. The buyer this site
   describes is an established expert with years behind them, so
   the median reader is 45 to 65, and 17px body at 1.65 is a
   young designer's number. It is also the single cheapest thing
   on the site to get right: nobody has ever left a page because
   the words were too easy to read.

   The deck's ladder is a set of RATIOS, not a set of pixel
   values: "Each step is roughly 1.4 times the one below it.
   Sizes may scale, but never the relationships." (p11) So every
   rung moves together and the ratios hold. Nothing here breaks
   the deck; it scales it.

     body     17    -> 19px      (+12%)
     lead     18-21 -> 20-23px
     caption  14    -> 15.5px
     action   14    -> 14.5px
     eyebrow  12    -> 12.5px, and tracking eased with it

   Line height goes up with size rather than staying put, because
   a longer line at a larger size needs more leading, not less.
   And the measure comes DOWN in ch: bigger type on the same
   column width is more characters per line, which is the thing
   that actually tires an older reader.
   ============================================================ */

.oyss {
  --t-eyebrow: .78125rem;                                  /* 12.5 */
  --t-caption: .96875rem;                                  /* 15.5 */
  --t-action:  .90625rem;                                  /* 14.5 */
  --t-body:    1.1875rem;                                  /* 19   */
  --t-lead:    clamp(1.25rem, 1.12rem + .5vw, 1.4375rem);  /* 20-23 */
  line-height: 1.7;
  /* 34rem at 19px is ~64ch, which is past the comfortable band.
     Measured in ch so it stays right whatever the rem is. */
  --measure: 62ch;
}

.oyss .lead { line-height: 1.5; }
.oyss .body { line-height: 1.72; }
.oyss .caption { line-height: 1.6; }

/* The eyebrow is small caps at 12.5px; .26em tracking was set for
   11px and opens too far once the glyphs grow. */
.oyss .eyebrow { letter-spacing: .2em; }

/* Long-form prose gets its own step up again. These are the two
   places on the site where somebody reads more than a sentence. */
.oyss .essay__body .p { font-size: 1.21875rem; line-height: 1.78; }   /* 19.5 */
.oyss .creed { line-height: 1.66; }

/* The manifest is a list of things you receive, so it is read
   item by item rather than scanned. */
.oyss .manifest__item { font-size: 1.15625rem; }                       /* 18.5 */
.oyss .manifest__item span { font-size: 1rem; line-height: 1.6; }      /* 16   */

/* The cue sheet's supporting copy was .caption, which at the old
   14px made the most substantive paragraphs on the page the
   smallest type in the section. */
.oyss .cuerow .caption { font-size: 1.0625rem; line-height: 1.68; }    /* 17   */
.oyss .terms p { font-size: 1.0625rem; line-height: 1.72; }
.oyss .ticklist li { font-size: 1.0625rem; line-height: 1.6; }

/* Form fields and their labels move with the body: a 60 year old
   filling in a $2,997 application should not be squinting at the
   thing that takes their money. */
.oyss .field__input, .oyss .field__label { font-size: 1.0625rem; }
.oyss .field__hint { font-size: .96875rem; }

/* A phone is held closer, so the step up is smaller there, and
   the measure is the viewport rather than the type. */
@media (max-width: 620px) {
  .oyss { --t-body: 1.125rem; --t-caption: .9375rem; }
  .oyss .essay__body .p { font-size: 1.15625rem; }
  .oyss .manifest__item { font-size: 1.09375rem; }
}


/* ============================================================
   40. KNOWING WHERE YOU ARE, AND WHAT HAPPENS NEXT
   ------------------------------------------------------------
   "great copy so people know which site they are at and how to
   perform the actions."

   Two different problems wearing one sentence.

   ORIENTATION. The masthead says OWN YOUR STAGE / STUDIO, and a
   stranger cannot tell from that whether this is a theater
   company, a design agency or a recording studio. The one word
   that fixes it is a descriptor, and the deck already has the
   slot: the horizontal lockup pairs the wordmark with a
   descriptor set beneath (p16, p19). It says STUDIO. It can say
   what kind. No bar, no strip: the words go inside the lockup
   that is already there, so nothing is added to the page.

   ACTION. Every button on the site named a destination and none
   of them said what happens after the click. A 60 year old
   about to spend $2,997 wants to know how long the form is,
   whether it takes their money now, and who reads it. That is
   not decoration, it is the difference between clicking and
   closing the tab. `.donext` puts that under the button, in the
   button's own column, at reading size.
   ============================================================ */

/* ---- 40.1 THE DESCRIPTOR ------------------------------------
   The lockup's second line becomes load-bearing. It stays the
   deck's letterspaced sans caption under the wordmark; it just
   carries information now instead of repeating the last word of
   the name. Tracking eases as the string gets longer, because
   .58em was set to make one five-letter word span a wordmark.
   ------------------------------------------------------------ */

.oyss .lockup__desc { letter-spacing: .24em; font-size: .5625rem; }
/* Below 460px the descriptor is competing with the burger for a 390px bar, and
   the burger has to win: it is the only way to the rest of the site. The
   descriptor drops to the word the deck specifies, and the full line still
   does the orienting job in the hero eyebrow one scroll down. */
@media (max-width: 460px) {
  .oyss .lockup__desc { letter-spacing: .3em; }
  .oyss .lockup__desc .lockup__what { display: none; }
}

/* ---- 40.2 WHAT HAPPENS NEXT ---------------------------------
   Sits under a primary action, never beside it, so the eye
   finishes the button and drops straight onto the consequence.
   ------------------------------------------------------------ */

.oyss .donext {
  margin-top: 1.05rem;
  max-width: 34rem;
  font-size: 1rem;
  line-height: 1.62;
  color: var(--slate);
}
.oyss .dark .donext, .oyss .stage .donext { color: rgba(248, 245, 242, .74); }
.oyss .donext b { font-weight: 600; color: var(--navy); }
.oyss .dark .donext b, .oyss .stage .donext b { color: var(--ivory); }

/* ---- 40.3 THE STEPS -----------------------------------------
   What actually happens between clicking apply and standing on
   the stage. Four lines, numbered because here the order IS the
   content, on a hairline rail rather than in cards.

   This is also the least AI-shaped block on the page, and that
   is not an accident: what makes copy read as human is knowing
   things a stranger could not have guessed. "Annette reads it
   herself" and "we hold the date for five working days" are
   facts about how a two person studio actually runs. No model
   writing generic landing copy produces those, because they are
   not generic and they are not copy: they are operations.
   ------------------------------------------------------------ */

.oyss .steps { margin-top: clamp(30px, 4vw, 46px); max-width: 46rem; }
.oyss .step {
  display: grid;
  grid-template-columns: 2.4rem minmax(0, 1fr);
  gap: clamp(12px, 1.6vw, 22px);
  padding: 1.15rem 0;
  border-top: 1px solid rgba(31, 30, 29, .13);
  align-items: baseline;
}
.oyss .step:last-child { border-bottom: 1px solid rgba(31, 30, 29, .13); }
.oyss .dark .step, .oyss .stage .step { border-top-color: rgba(228, 218, 214, .16); }
.oyss .dark .step:last-child, .oyss .stage .step:last-child { border-bottom-color: rgba(228, 218, 214, .16); }
.oyss .step__n {
  font-family: var(--serif); font-weight: 700;
  font-size: .95rem;
  letter-spacing: .04em;
  color: #B91C1C;
  line-height: 1.4;
}
.oyss .dark .step__n, .oyss .stage .step__n { color: var(--gold); }
.oyss .step__t { font-size: 1.0625rem; line-height: 1.68; color: var(--navy); }
.oyss .dark .step__t, .oyss .stage .step__t { color: var(--ivory-70); }
.oyss .step__t b { font-weight: 600; }
.oyss .step__t strong { font-weight: 600; color: var(--navy); }
.oyss .dark .step__t strong, .oyss .stage .step__t strong { color: var(--ivory); }

/* ---- 40.4 THE ASIDE -----------------------------------------
   One editorial device the whole site shares and nothing else
   on the internet has in quite this shape: a short line hung in
   the left margin, set in the serif, beside a section it
   comments on. It is the voice of the studio talking about its
   own page rather than to the customer.

   It exists because every section on this site was addressing
   the reader in the same register, and a page where nothing
   ever changes tone is a page nobody wrote.
   ------------------------------------------------------------ */

.oyss .marginal {
  position: relative;
  padding-left: clamp(14px, 1.4vw, 20px);
  border-left: 2px solid var(--gold);
  max-width: 26rem;
  font-family: var(--sans); font-weight: 400;
  font-size: 1.1875rem;
  font-style: italic;
  line-height: 1.5;
  color: var(--slate);
}
.oyss .dark .marginal, .oyss .stage .marginal { color: var(--ivory-70); }
.oyss .marginal cite {
  display: block;
  margin-top: .7rem;
  font-family: var(--sans);
  font-style: normal;
  font-size: var(--t-eyebrow);
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: #B91C1C;
}
.oyss .dark .marginal cite, .oyss .stage .marginal cite { color: var(--gold); }


/* ============================================================
   41. BREAKING THE METRONOME
   ------------------------------------------------------------
   "The layout is fine but it is still giving AI design vibes."

   What was left was RHYTHM, in the most literal sense. Every
   section on the site used `--bay` for its padding, so the
   vertical beat between one idea and the next was identical
   eleven times running. No human lays out a long page that way:
   they give the important section more air and push two related
   ones together, and the reader feels the argument grouping
   itself without ever noticing why.

   So the padding is set by hand, in three sizes, by what the
   section is doing rather than by a formula:

     .bay--open   the page's two or three big moments
     .bay         the default
     .bay--tight  a section that belongs to the one above it

   Nothing here is a new component. It is the same page, breathing
   unevenly on purpose.
   ============================================================ */

.oyss .bay--open  { padding: clamp(104px, 14vw, 190px) 0; }
.oyss .bay--tight { padding: clamp(44px, 5vw, 74px) 0; }
/* A tight section following an open one needs its top seam pulled
   in or the two read as one long pause. */
.oyss .bay--open + .bay--tight { padding-top: clamp(30px, 3.5vw, 52px); }


/* ============================================================
   42. FEEDBACK 2.0
   ------------------------------------------------------------
   Twenty-one annotated screenshots. The through-line in most of
   them is the same one this project keeps relearning: a device
   that exists to look designed reads as machine-made, and the
   fix is to make it either do work or go away.
   ============================================================ */

/* ---- 42.1 THE BIG LINES (his note, and his find) ------------
   "Lets use this big lines in the footer I really liked and then
   out normal footer."

   Right call. The tagline is the single strongest thing the
   brand owns and it was set in 19px sans halfway down a column.
   At display scale it does what the deck's closing panel does
   (p25). Split color is the deck's own: the promise in ivory,
   the payoff in gold.
   ------------------------------------------------------------ */

.oyss .footer__lines {
  font-family: var(--serif); font-weight: 700;
  font-size: clamp(2.1rem, 1.2rem + 4vw, 4.6rem);
  line-height: 1.02;
  letter-spacing: -.02em;
  color: var(--ivory);
  padding: clamp(20px, 3vw, 40px) 0 clamp(30px, 4vw, 54px);
  margin-bottom: clamp(28px, 3.5vw, 48px);
  border-bottom: 1px solid rgba(228, 218, 214, .14);
}
.oyss .footer__lines span { display: block; }
.oyss .footer__lines--gold { color: var(--gold); }

/* The closing thought, where the domain used to sit. */
.oyss .footer__note {
  font-family: var(--sans); font-weight: 400;
  font-style: italic;
  font-size: 1.0625rem;
  color: var(--gold);
  letter-spacing: .01em;
}

/* ---- 42.2 THE LOGO, RUNNING ---------------------------------
   "Can the logo be continuous motion."

   The mark struck once on load and then sat still, which is a
   cue rather than a sign of life. It runs now, but on the
   brand's terms: silk that is moving does not flash, it BREATHES.
   So the A's opacity and the arch's width drift on a slow nine
   second cycle, a few percent either side of full, out of phase
   with each other so the pair never pulses in unison.
   Nothing moves position, nothing scales enough to read as an
   animation, and at 34px what a reader perceives is that the
   light is live rather than drawn.

   Both keyframes stay inside the reduced-motion guard the rest
   of section 26 already sits in, so a reader who has asked for
   stillness gets a static, fully lit mark.
   ------------------------------------------------------------ */

@media (prefers-reduced-motion: no-preference) {
  /* The strike still runs first; the breath takes over after it,
     which is what the delay is buying. */
  .oyss .lockup--motion .mark__a {
    animation: mark-rise 760ms var(--fade-up) both,
               mark-breathe 9s ease-in-out 1.1s infinite;
  }
  .oyss .lockup--motion .mark__arch {
    animation: arch-bloom 620ms var(--fade-up) 280ms both,
               arch-breathe 9s ease-in-out 1.4s infinite;
  }
  @keyframes mark-breathe {
    0%, 100% { opacity: 1; }
    46%      { opacity: .88; }
  }
  @keyframes arch-breathe {
    0%, 100% { transform: scale(1); opacity: 1; }
    38%      { transform: scale(.9); opacity: .84; }
  }
  /* Hovering still brightens it, and while the pointer is down
     the breath holds so the mark feels answerable. */
  .oyss .lockup:active .mark__a,
  .oyss .lockup:active .mark__arch { animation-play-state: paused; }
}

/* ---- 42.3 THE RIG LIGHTS UNDER THE POINTER ------------------
   "On hovering each panel section should light up."

   The rig already cycles its key light on a timer, the way a
   producer switches cameras. Hovering now takes the desk: the
   frame under the pointer lights and the automatic cue steps
   aside until the pointer leaves. That is exactly what a vision
   mixer does, so the interaction and the metaphor are the same
   thing rather than two things.

   The class is applied by JS (module 18) rather than by :hover
   alone, because the timer also has to stop, and CSS cannot tell
   the timer anything.
   ------------------------------------------------------------ */

.oyss .rig--live .frame { cursor: default; }
@media (hover: hover) and (pointer: fine) {
  .oyss .rig--live .frame::before,
  .oyss .rig--live .frame img,
  .oyss .rig--live .frame::after { transition-duration: 260ms; }
  /* A frame the pointer is NOT on, while some frame is hovered,
     dips further than its resting state, so the lit one reads. */
  .oyss .rig--live.rig--held .frame:not(.on) img { filter: brightness(.34) saturate(.6); }
}

/* ---- 42.4 THE CUE LIST, ANIMATED ----------------------------
   "This is very common style, keep this list style but innovate
   and try something new with animation."

   The list stays. What was common about it was that the rail was
   drawn, the marker slid down it, and each row faded up: three
   generic scroll effects layered on one component.

   The new behavior is the brand's own and it is one idea rather
   than three. Each cue is a LIGHTING STATE, so the rail is a
   dimmer track and the rows behave like channels on it: the row
   the reader is level with comes to full, the rows behind it
   stay at a readable half, and the rows ahead sit at a quarter
   with their numbers unlit. Passing a row does not just reveal
   it, it HANDS THE LIGHT ON, and the number strikes gold at the
   moment it takes over.

   That is a real production behavior rather than a scroll
   trick, it uses the one motif the deck allows, and it makes the
   list readable as a sequence in a way a uniform fade never did.
   ------------------------------------------------------------ */

.oyss .cuerow {
  transition: opacity 620ms var(--settle), filter 620ms var(--settle);
}
.oyss .cuesheet--dimmer .cuerow { opacity: .38; filter: saturate(.55); }
.oyss .cuesheet--dimmer .cuerow.passed { opacity: .62; filter: saturate(.8); }
.oyss .cuesheet--dimmer .cuerow.live { opacity: 1; filter: none; }

/* The number is the channel fader's own indicator. */
.oyss .cuesheet--dimmer .cuerow__n {
  position: relative;
  transition: color 500ms var(--settle), transform 620ms var(--fade-up);
}
.oyss .cuesheet--dimmer .cuerow.live .cuerow__n { color: #B91C1C; transform: translateX(2px); }
.oyss .dark .cuesheet--dimmer .cuerow.live .cuerow__n,
.oyss .stage .cuesheet--dimmer .cuerow.live .cuerow__n { color: var(--gold); }

/* The pool that marks the live cue: the mark's own ellipse,
   drawn open from nothing as the row takes the light. */
.oyss .cuesheet--dimmer .cuerow__n::after {
  content: '';
  position: absolute; left: 0; bottom: -.6rem;
  width: 30px; height: 5px;
  border-radius: 50%;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left center;
  opacity: 0;
  transition: transform 560ms var(--fade-up), opacity 400ms var(--settle);
}
.oyss .cuesheet--dimmer .cuerow.live .cuerow__n::after { transform: scaleX(1); opacity: 1; }

/* The rail stops being a decorative line with a bead on it and
   becomes the dimmer track: a channel that fills to wherever the
   light has reached. */
.oyss .cuesheet--dimmer .cuesheet__rail::before {
  content: '';
  position: absolute; left: 0; top: 0; width: 100%;
  height: var(--cue-fill, 0%);
  background: linear-gradient(180deg, var(--gold-40), var(--gold));
  transition: height 620ms var(--settle);
}

@media (prefers-reduced-motion: reduce) {
  .oyss .cuesheet--dimmer .cuerow { opacity: 1; filter: none; }
  .oyss .cuesheet--dimmer .cuerow__n::after { transform: scaleX(1); opacity: 1; }
}

/* ---- 42.5 THE ASSESSMENT, ONE QUESTION AT A TIME ------------
   "Do not create assessment as a long form, create it in a box
   once the person select question 1 question2 pops up and then
   next and back option."

   He is right and the reason is completion rate. Eight questions
   stacked on one page is a wall: the reader can see how much is
   left before they have answered anything, and the thing they
   are being asked to do looks like work. One question in a box
   with next and back is the same eight questions and a fraction
   of the perceived cost.

   The markup does not change. Every fieldset is still in the
   page, still a real form, still submits and still works with JS
   off: the stepper is applied on top by JS, so nothing here
   removes a question from anybody.
   ------------------------------------------------------------ */

.oyss .quiz .qstep { display: none; }
.oyss .quiz .qstep.is-current { display: block; }
/* Fixed height stops the box resizing between a three line
   question and a one line question, which is the thing that
   makes a stepper feel cheap. Content-driven below 640px, where
   a min-height would just add dead space. */
.oyss .quiz__stage { min-height: 25rem; }
@media (max-width: 640px) { .oyss .quiz__stage { min-height: 0; } }

/* The step counter is a lighting cue, not a progress bar: one
   pip per question, the answered ones lit. */
.oyss .quiz__pips { display: flex; gap: 7px; align-items: center; }
.oyss .quiz__pip {
  width: 26px; height: 4px; border-radius: 2px;
  background: rgba(31, 30, 29, .16);
  transition: background 380ms var(--settle), transform 380ms var(--fade-up);
}
.oyss .quiz__pip.done { background: var(--gold); }
.oyss .quiz__pip.now  { background: #B91C1C; transform: scaleY(1.9); }

.oyss .quiz__bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  padding-bottom: 1.4rem; margin-bottom: 2rem;
  border-bottom: 1px solid var(--ash);
}
.oyss .quiz__count {
  font-size: var(--t-caption); color: var(--slate);
  letter-spacing: .1em; text-transform: uppercase; font-weight: 600;
}

.oyss .quiz__nav {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  padding-top: 1.6rem; border-top: 1px solid var(--ash);
}
.oyss .quiz__back {
  font-size: var(--t-action); font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--slate); cursor: pointer;
  background: none; border: 0; padding: .6rem 0;
}
.oyss .quiz__back:hover { color: var(--navy); }
.oyss .quiz__back[disabled] { opacity: .3; cursor: default; }
.oyss .quiz__hint { font-size: var(--t-caption); color: var(--slate); }

/* Choosing advances on its own after a beat, so the next button
   is a fallback rather than the main path. The beat exists so
   the reader sees their own answer register before the question
   changes: instant advance reads as the page jumping. */
.oyss .quiz .choice { transition: opacity 200ms var(--settle); }
.oyss .quiz--advancing .choice:not(.is-picked) { opacity: .4; }

@media (prefers-reduced-motion: no-preference) {
  .oyss .quiz .qstep.is-current { animation: qstep-in 420ms var(--fade-up) both; }
  @keyframes qstep-in {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
  }
}


/* ============================================================
   43. THE PROMPTS
   ------------------------------------------------------------
   "Add pop-up also on the site... two bottom bar for desktop and
   top bar for mobile and exit intent for all the three types of
   layout mobile desktop and tablet."

   Three surfaces, one rule: a prompt has to be worth the
   interruption or it damages a premium brand faster than it
   converts. So each one is EARNED rather than timed:

     the bar        appears after the reader has passed the price
                    section, because before that they do not yet
                    know what they would be applying for
     the second bar only on a page where the first is irrelevant
                    (a form page already has the action on screen)
     exit intent    once per visitor per week, never on a page
                    where they are mid-form, and never on touch
                    until they have actually read something

   Everything is dismissible, everything remembers, and nothing
   ever covers the primary action.
   ============================================================ */

/* ---- 43.1 THE BAR -------------------------------------------
   Bottom on desktop and tablet, top on a phone. The reason is
   the thumb: on a phone the bottom of the screen is where the
   browser chrome and the reader's own hand live, and a bar there
   fights both. At the top it sits under the masthead, which the
   reader is already ignoring.
   ------------------------------------------------------------ */

.oyss .prompt {
  position: fixed;
  left: 0; right: 0;
  z-index: 60;
  background: rgba(22, 21, 20, .96);
  backdrop-filter: saturate(140%) blur(16px);
  -webkit-backdrop-filter: saturate(140%) blur(16px);
  color: var(--ivory);
  transform: translateY(110%);
  transition: transform 620ms var(--fade-up), opacity 400ms var(--settle);
  opacity: 0;
  will-change: transform;
}
.oyss .prompt[hidden] { display: none !important; }
.oyss .prompt.is-in { transform: none; opacity: 1; }

/* desktop and tablet: bottom */
.oyss .prompt--bottom { bottom: 0; border-top: 1px solid var(--gold-40); }
/* phone: top, under the bar */
.oyss .prompt--top {
  top: 0; bottom: auto;
  transform: translateY(-110%);
  border-bottom: 1px solid var(--gold-40);
  padding-top: var(--oyss-mh, 78px);
}

.oyss .prompt__inner {
  display: flex; align-items: center; gap: clamp(14px, 2.4vw, 34px);
  padding: clamp(14px, 1.5vw, 20px) var(--gutter);
  max-width: var(--wrap); margin: 0 auto;
}
.oyss .prompt__text { display: block; flex: 1 1 auto; min-width: 0; }
/* These are spans, so without a display they are INLINE and the
   two lines run together as one sentence. Third time this exact
   bug has been paid for on this project: a span with no display
   is inline, whatever the class name implies. */
.oyss .prompt__t {
  display: block;
  font-family: var(--serif); font-weight: 700;
  font-size: clamp(1.05rem, .95rem + .5vw, 1.4rem);
  line-height: 1.2;
  color: var(--ivory);
}
.oyss .prompt__m {
  display: block;
  font-size: var(--t-caption);
  color: rgba(248, 245, 242, .7);
  margin-top: .3rem;
}
.oyss .prompt .btn { flex: none; padding: .82rem 1.5rem; }
.oyss .prompt__x {
  flex: none;
  width: 42px; height: 42px;
  border: 0; background: none; cursor: pointer;
  color: rgba(248, 245, 242, .55);
  font-size: 1.4rem; line-height: 1;
  border-radius: 50%;
  transition: color 200ms var(--settle), background 200ms var(--settle);
}
.oyss .prompt__x:hover { color: var(--ivory); background: rgba(248, 245, 242, .08); }
.oyss .prompt__x:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

@media (max-width: 760px) {
  .oyss .prompt__inner { gap: 12px; padding: 12px var(--gutter); flex-wrap: wrap; }
  .oyss .prompt__t { font-size: 1.0625rem; }
  .oyss .prompt__m { display: none; }
  .oyss .prompt .btn { width: 100%; order: 3; justify-content: center; padding: .9rem 1rem; }
  .oyss .prompt__x { order: 2; margin-left: auto; }
  .oyss .prompt__text { flex: 1 1 70%; }
}

/* ---- 43.2 EXIT INTENT ---------------------------------------
   One modal, all three layouts. On a pointer device it fires on
   the mouse leaving through the top of the window; on touch, where
   there is no such gesture, it fires on a fast upward flick
   toward the address bar after real engagement, which is the
   closest honest equivalent.

   Built as a real dialog: focus goes in, Escape closes, the
   background is inert, and focus returns to where it was.
   ------------------------------------------------------------ */

.oyss .exit {
  position: fixed; inset: 0; z-index: 80;
  display: grid; place-items: center;
  padding: var(--gutter);
  background: rgba(13, 12, 12, .74);
  opacity: 0;
  transition: opacity 380ms var(--settle);
}
.oyss .exit[hidden] { display: none !important; }
.oyss .exit.is-in { opacity: 1; }

.oyss .exit__card {
  position: relative;
  width: min(560px, 100%);
  background: var(--navy);
  border: 1px solid var(--gold-40);
  padding: clamp(30px, 4vw, 52px);
  overflow: hidden;
  transform: translateY(16px) scale(.985);
  transition: transform 520ms var(--fade-up);
}
.oyss .exit.is-in .exit__card { transform: none; }
/* The beam, at card scale. The one motif, doing the one job. */
.oyss .exit__card::before {
  content: '';
  position: absolute; left: 50%; top: -46%;
  width: 128%; aspect-ratio: 1 / 1;
  transform: translateX(-50%);
  background: radial-gradient(50% 50% at 50% 50%, rgba(224, 90, 90, .16) 0%, transparent 62%);
  pointer-events: none;
}
.oyss .exit__card > * { position: relative; }

.oyss .exit__eyebrow {
  font-size: var(--t-eyebrow); font-weight: 600;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 1rem;
}
.oyss .exit__t {
  font-family: var(--serif); font-weight: 700;
  font-size: clamp(1.6rem, 1.2rem + 1.8vw, 2.4rem);
  line-height: 1.12; color: var(--ivory);
  text-wrap: balance;
}
.oyss .exit__p {
  margin-top: 1.2rem;
  color: rgba(248, 245, 242, .78);
  font-size: 1.0625rem; line-height: 1.6;
  max-width: 36ch;
}
.oyss .exit__actions { display: flex; flex-wrap: wrap; gap: 1rem 1.4rem; align-items: center; margin-top: 2rem; }
.oyss .exit__no {
  background: none; border: 0; cursor: pointer; padding: .6rem 0;
  font-size: var(--t-action); font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: rgba(248, 245, 242, .6);
}
.oyss .exit__no:hover { color: var(--ivory); }
.oyss .exit__x {
  position: absolute; top: 10px; right: 10px;
  width: 44px; height: 44px; border: 0; background: none; cursor: pointer;
  color: rgba(248, 245, 242, .5); font-size: 1.5rem; line-height: 1;
}
.oyss .exit__x:hover { color: var(--ivory); }
.oyss .exit__x:focus-visible, .oyss .exit__no:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  .oyss .prompt, .oyss .exit, .oyss .exit__card { transition: none; }
}

/* ---- 42.6 THE PANELIST FRAME, ASSEMBLING --------------------
   "Create a video here how it looks, it can be a premium
   animated video explaining everything."

   A video would be the wrong tool. The thing being explained is
   how a frame gets dressed, and the dressing is live text and
   vector: baking it into an mp4 makes it soft on a retina
   screen, unreadable at small sizes, and a re-render away from
   any copy change.

   So it is animated in the browser instead, as a four beat
   sequence on the real frame: the backdrop, the light, the name
   plate, the on-air marker. It runs once when scrolled to,
   replays on click, and rests fully assembled with JS off,
   because the finished state is the useful one.
   ------------------------------------------------------------ */

.oyss .build {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: #161514;
  border: 1px solid rgba(228, 218, 214, .16);
  cursor: pointer;
}
.oyss .build img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 34%;
}
.oyss .build__key {
  position: absolute; left: 50%; top: -52%;
  width: 118%; aspect-ratio: 1 / 1;
  transform: translateX(-50%);
  background: radial-gradient(50% 50% at 50% 50%, rgba(255, 222, 216, .22) 0%, transparent 62%);
  mix-blend-mode: screen;
  pointer-events: none;
}
.oyss .build__lip {
  position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: linear-gradient(90deg, rgba(224, 90, 90, 0) 0%, rgba(224, 90, 90, .85) 22%,
                                     rgba(224, 90, 90, .85) 78%, rgba(224, 90, 90, 0) 100%);
  transform-origin: center;
}
.oyss .build__mark {
  position: absolute; left: 12px; top: 11px;
  display: flex; align-items: center; gap: .5rem;
}
.oyss .build__mark svg { width: 20px; height: 20px; }
.oyss .build__plate {
  position: absolute; right: 0; bottom: 0;
  max-width: 84%;
  padding: .6rem .9rem .75rem 1.1rem;
  text-align: right;
  background: linear-gradient(270deg, rgba(19, 18, 17, .9) 0%, rgba(19, 18, 17, .78) 62%, rgba(19, 18, 17, 0) 100%);
}
.oyss .build__role {
  font-size: .5625rem; font-weight: 600; letter-spacing: .3em;
  text-transform: uppercase; color: rgba(248, 245, 242, .62); line-height: 1;
}
.oyss .build__name { font-family: var(--serif); font-weight: 700; font-size: 1.15rem; color: var(--ivory); margin-top: .22rem; }
.oyss .build__sub { font-size: .6875rem; color: var(--gold); margin-top: .12rem; }
.oyss .build__live {
  position: absolute; right: 12px; top: 11px;
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .3rem .55rem;
  border: 1px solid var(--gold-40);
  font-size: .5625rem; font-weight: 600; letter-spacing: .22em;
  text-transform: uppercase; color: var(--gold);
  background: rgba(19, 18, 17, .6);
}
.oyss .build__live::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--gold); }

/* The step readout under the frame: what the reader is watching
   arrive, named, so the sequence explains rather than decorates. */
.oyss .build__steps { display: flex; flex-wrap: wrap; gap: .5rem 1.5rem; margin-top: 1rem; }
.oyss .build__step {
  font-size: var(--t-caption); color: var(--ivory-46);
  display: inline-flex; align-items: center; gap: .5rem;
  transition: color 400ms var(--settle);
}
.oyss .build__step::before {
  content: ''; width: 14px; height: 3px; border-radius: 2px;
  background: rgba(228, 218, 214, .28);
  transition: background 400ms var(--settle);
}
.oyss .build__step.on { color: var(--ivory); }
.oyss .build__step.on::before { background: var(--gold); }

/* The assembling states. Resting = finished, so no JS means the
   frame is simply dressed and correct. */
@media (prefers-reduced-motion: no-preference) {
  .oyss .build[data-build] .build__key,
  .oyss .build[data-build] .build__lip,
  .oyss .build[data-build] .build__mark,
  .oyss .build[data-build] .build__plate,
  .oyss .build[data-build] .build__live { transition: opacity 520ms var(--settle), transform 640ms var(--fade-up); }
  .oyss .build[data-build="0"] img { filter: brightness(.42) saturate(.6); }
  .oyss .build[data-build] img { transition: filter 700ms var(--settle); }
  .oyss .build[data-build="0"] .build__key,
  .oyss .build[data-build="0"] .build__lip,
  .oyss .build[data-build="0"] .build__mark,
  .oyss .build[data-build="0"] .build__plate,
  .oyss .build[data-build="0"] .build__live { opacity: 0; }
  .oyss .build[data-build="1"] .build__lip,
  .oyss .build[data-build="1"] .build__mark,
  .oyss .build[data-build="1"] .build__plate,
  .oyss .build[data-build="1"] .build__live { opacity: 0; }
  .oyss .build[data-build="2"] .build__plate,
  .oyss .build[data-build="2"] .build__live { opacity: 0; }
  .oyss .build[data-build="2"] .build__plate { transform: translateX(14px); }
  .oyss .build[data-build="3"] .build__live { opacity: 0; }
  .oyss .build[data-build="1"] .build__lip { transform: scaleX(0); }
}

/* Spans again. The plate's three lines stack; without a display
   they set as one horizontal run. */
.oyss .build__plate,
.oyss .build__role, .oyss .build__name, .oyss .build__sub { display: block; }
.oyss .build { max-width: 34rem; }

/* ---- 42.7 THE ANNOTATION, HUMANISED ------------------------
   "This style is an ai style please change it to something more
   of humanize design" - twice, on two components that were the
   same idea: small gray text next to a gold marker.

   That IS the generated-UI pattern: a decorative rule, a caption
   color, and a sentence that could belong to any product. The
   replacement is an editorial footnote instead of a UI callout:
   set in the serif at reading size, indented like a note in a
   printed book, marked by a small raised numeral rather than a
   colored bar. It reads as something a person wrote in the
   margin of a proof.
   ------------------------------------------------------------ */

/* Feedback 3.0, notes 2 and 4: "A random number 2 is showing up, please fix
   it" and "Remove number 3 from here".

   They were footnote markers, and that is exactly why they read as random: a
   footnote numeral is only legible when something earlier in the text carries
   the matching reference, and nothing here did. Three of them were live, one
   per page section, numbered by where the note sat rather than by anything a
   reader could follow.

   The numeral goes. What made these read as written by a person was never the
   marker, it was the setting: the serif at reading size, held in from the
   column it comments on, on a shorter measure than the prose above it. That
   is what an aside looks like in print, and it needs no marker at all. */

.oyss .aside-note {
  position: relative;
  margin-top: 2rem;
  padding-left: 1.6rem;
  max-width: 40rem;
  font-family: var(--serif); font-weight: 700;
  font-size: 1.15rem;
  line-height: 1.56;
  color: var(--slate);
  border: 0;
}
.oyss .dark .aside-note, .oyss .stage .aside-note { color: var(--ivory-70); }

/* The two components this replaces. */
.oyss .rig__note {
  display: block;
  position: relative;
  margin-top: 1.6rem;
  padding-left: 1.6rem;
  max-width: 44rem;
  font-family: var(--serif); font-weight: 700;
  font-size: 1.15rem;
  line-height: 1.56;
  color: var(--ivory-70);
}
.oyss .essay__note {
  border-left: 0;
  padding-left: 1.6rem;
  position: relative;
  font-family: var(--serif); font-weight: 700;
  font-size: 1.15rem;
  line-height: 1.56;
  max-width: 30rem;
}

/* ---- 42.8 THE SPEC ------------------------------------------
   "This section is great but something feels missing here."
   What was missing was the specification. The reader had been
   told the room looks produced and given nothing to check that
   against. Four numbers, set as a spec sheet: a term and its
   consequence, hairline separated, no boxes.
   ------------------------------------------------------------ */

.oyss .spec { margin-top: 1.8rem; }
.oyss .spec li {
  padding: .85rem 0;
  border-top: 1px solid rgba(228, 218, 214, .16);
}
.oyss .spec li:last-child { border-bottom: 1px solid rgba(228, 218, 214, .16); }
.oyss .spec b {
  display: block;
  font-family: var(--serif); font-weight: 700;
  font-size: 1.2rem; color: var(--ivory);
  letter-spacing: -.005em;
}
.oyss .spec span {
  display: block;
  font-size: var(--t-caption); line-height: 1.55;
  color: var(--ivory-46); margin-top: .18rem;
}

/* ---- 42.9 THE EXECUTION PAGE --------------------------------
   "When you say to sign you should give option to sign at the
   end it just looks another form to nothing looks like an
   agreement."

   The block WAS at the end. What was wrong is that it looked
   like a web form: a field label, an input with a placeholder,
   a submit button. The last page of a contract does not look
   like that, and a page that takes $2,997 on a signature has to
   feel like the document it closes.

   So it is set as an execution page: the witness clause, then
   two signature panels side by side, each with a ruled signature
   line above a printed name and a date, the way an executed
   agreement is laid out on paper. The client's panel is
   fillable; the studio's is countersigned and shown as such, so
   the reader can see this is an agreement between two parties
   rather than a form they are submitting into a void.
   ------------------------------------------------------------ */

.oyss .exec__witness {
  margin-top: 3rem;
  font-family: var(--serif); font-weight: 700;
  font-size: 1.15rem;
  line-height: 1.55;
  color: var(--ivory-70);
  max-width: 42rem;
}

.oyss .exec {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(26px, 4vw, 64px);
  margin-top: clamp(30px, 4vw, 48px);
}
@media (max-width: 700px) { .oyss .exec { grid-template-columns: 1fr; gap: 40px; } }

.oyss .exec__for {
  font-size: var(--t-eyebrow); font-weight: 600;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 1.4rem;
}

/* The signature line. The input is invisible furniture: no box,
   no fill, no placeholder. What the reader sees is their name
   appearing in the signature face on a ruled line. */
.oyss .exec__sign { position: relative; display: block; min-height: 3.4rem; }
.oyss .exec__sign .sig {
  position: absolute; left: 0; bottom: .2rem;
  pointer-events: none;
  max-width: 100%; overflow: hidden; white-space: nowrap;
}
.oyss .exec__input {
  width: 100%;
  background: none;
  border: 0;
  padding: 0 0 .2rem;
  min-height: 3.4rem;
  font-family: var(--serif); font-weight: 700;
  font-size: 1.8rem;
  color: transparent;
  caret-color: var(--gold);
}
.oyss .exec__input:focus { outline: 0; }
.oyss .exec__sign:focus-within .exec__rule,
.oyss .exec__sign:focus-within + .exec__rule { background: var(--gold); }

.oyss .exec__party--them .sig--them {
  display: block;
  min-height: 3.4rem;
  padding-bottom: .2rem;
  display: flex; align-items: flex-end;
  opacity: .5;
}

.oyss .exec__rule {
  height: 1px;
  background: rgba(228, 218, 214, .42);
  margin: 0 0 .9rem;
  transition: background 240ms var(--settle);
}

.oyss .exec__meta { display: grid; grid-template-columns: auto 1fr; gap: .3rem 1rem; }
.oyss .exec__meta dt {
  font-size: var(--t-eyebrow); font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--ivory-46);
}
.oyss .exec__meta dd { margin: 0; font-size: var(--t-caption); color: var(--ivory-70); }
.oyss .exec__meta dd#sig-date { color: var(--gold); }

/* On paper the two panels sit side by side and the ink is black. */
@media print {
  .oyss .exec { break-inside: avoid; }
  .oyss .exec__input { color: inherit; }
}

/* ============================================================
   44. FEEDBACK 3.0 - THE INTERIOR PAGES
   ------------------------------------------------------------
   "And my partner is saying only the homepage is looking, the
   rest of the pages needed an upgrade in terms of design and
   copy."

   The diagnosis was countable before it was aesthetic. The home
   page carries twelve pictures, nine section shapes and six
   components that exist nowhere else. Every other page carried
   ONE picture, its hero, and then repeated the same three
   objects in the same order on every one of them: a row of
   bordered cards with a numeral, a two column tick list, and a
   pair of bordered columns. Three pages built from the same kit
   in the same sequence read as one template however good the
   words in them are.

   So this section is mostly SUBTRACTION plus one device per
   page that belongs only to that page:

     experience   a contents list with leaders, and the division
                  of responsibilities set as what it actually is,
                  an extract from the agreement
     panelists    the run of show, with the reader's ten minutes
                  marked in it
     faq          a standing index beside the questions
     about        nothing new; the grid at the end becomes prose

   The cards, the ledger boxes and the tick grids are gone from
   these pages. Nothing here introduces a color, a typeface or a
   motion rule that was not already in the deck.
   ============================================================ */

/* ---- 44.1 THE PREMISE ---------------------------------------
   A page that sells three months of work should open in prose,
   the way the home page does, not in three boxes. One statement
   at display size, then the argument in two unequal columns so
   the block has a shape of its own.
   ------------------------------------------------------------ */

.oyss .premise { max-width: 62rem; }
.oyss .premise__lead {
  font-family: var(--serif); font-weight: 700;
  font-size: clamp(1.5rem, 1.05rem + 1.9vw, 2.25rem);
  line-height: 1.2; letter-spacing: -.01em;
  max-width: 27ch;
  color: var(--ink);
}
.oyss .dark .premise__lead, .oyss .stage .premise__lead { color: var(--ivory); }
.oyss .premise__cols {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: clamp(26px, 4vw, 64px);
  margin-top: clamp(26px, 3.4vw, 44px);
}
.oyss .premise__cols p + p { margin-top: 1.1rem; }
@media (max-width: 860px) {
  .oyss .premise__cols { grid-template-columns: 1fr; }
}

/* ---- 44.2 THE CONTENTS --------------------------------------
   What was a sixteen item tick grid, and before that the same
   sixteen item tick grid on two pages at once.

   A tick list is a feature grid, which is the shape a product
   page reaches for when it wants length to stand in for
   substance. This is the same information set as the contents
   page of a printed document: the item on the left, the quantity
   held out at the right hand edge. It reads as a thing that was
   itemized rather than a thing that was listed, which is what a
   schedule attached to a contract actually is.
   ------------------------------------------------------------ */

.oyss .contents { margin-top: clamp(22px, 3vw, 36px); }
.oyss .contents li {
  display: flex; align-items: baseline; gap: .75rem;
  padding: .78rem 0;
  border-top: 1px solid rgba(31, 30, 29, .12);
  font-size: 1.0625rem; line-height: 1.45;
  color: var(--ink);
}
.oyss .contents li:last-child { border-bottom: 1px solid rgba(31, 30, 29, .12); }
.oyss .dark .contents li, .oyss .stage .contents li {
  color: var(--ivory); border-top-color: rgba(228, 218, 214, .15);
}
.oyss .dark .contents li:last-child, .oyss .stage .contents li:last-child {
  border-bottom-color: rgba(228, 218, 214, .15);
}
/* The leader was a dotted rule between the item and its quantity.
   Feedback 4.0, notes 6 and 7, on both lists: "Not liking this at
   all" and "Same here". It is gone. The spacer stays and still
   pushes the quantity to the right hand edge, so the column of
   figures holds; there is simply nothing drawn across the gap. */
.oyss .contents__dot { flex: 1 1 auto; min-width: 1.5rem; }
.oyss .contents__qty {
  flex: 0 0 auto;
  font-family: var(--serif); font-weight: 700;
  font-size: 1.0625rem; color: var(--red);
  font-variant-numeric: tabular-nums;
}
.oyss .dark .contents__qty, .oyss .stage .contents__qty { color: var(--gold); }
.oyss .contents__note {
  display: block; margin-top: .2rem;
  font-size: var(--t-caption); line-height: 1.5; color: var(--slate);
}
.oyss .dark .contents__note, .oyss .stage .contents__note { color: var(--ivory-46); }
.oyss .contents__item { flex: 0 1 auto; max-width: 40rem; }

/* ---- 44.3 THE CLAUSE ----------------------------------------
   The division of responsibilities used to be two bordered
   columns headed "We handle" and "We do not handle", which is a
   comparison table, and a comparison table is a sales object.

   It is not a sales object. It is the most load bearing thing on
   the page for a studio that must not over promise: it is where
   the site says, before any money moves, that nobody here
   guarantees an audience. So it is set as what it is, an extract
   from the agreement the reader is going to sign, carrying that
   agreement's own clause numbers so the two can be read against
   each other.
   ------------------------------------------------------------ */

.oyss .clause {
  margin-top: clamp(26px, 3.4vw, 44px);
  max-width: 54rem;
  border-top: 2px solid var(--red);
}
.oyss .clause__row {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  gap: clamp(14px, 2vw, 28px);
  padding: 1.5rem 0;
  border-bottom: 1px solid rgba(31, 30, 29, .12);
}
.oyss .clause__n {
  font-size: var(--t-eyebrow); font-weight: 700; letter-spacing: .2em;
  text-transform: uppercase; color: var(--red);
  padding-top: .3em;
  font-variant-numeric: tabular-nums;
}
.oyss .clause__t {
  font-size: 1.0625rem; line-height: 1.58; color: var(--ink);
}
.oyss .clause__t + .clause__t { margin-top: .7rem; }
.oyss .dark .clause__row, .oyss .stage .clause__row {
  border-bottom-color: rgba(228, 218, 214, .15);
}
.oyss .dark .clause__t, .oyss .stage .clause__t { color: var(--ivory-70); }
.oyss .dark .clause__n, .oyss .stage .clause__n { color: var(--gold); }
@media (max-width: 640px) {
  .oyss .clause__row { grid-template-columns: 1fr; gap: .5rem; }
  .oyss .clause__n { padding-top: 0; }
}

/* ---- 44.4 THE RUN OF SHOW -----------------------------------
   The panelist page sells ten minutes inside somebody else's
   ninety, and it was selling them with the same three cards the
   host page used. The ten minutes are the product, so they get
   drawn: the running order of a real event with one row lit and
   the rest of the show around it. That also answers the two
   questions that page keeps being asked, which are how long am I
   on and what happens either side of me.

   The lit row is the only warm thing in the block. Everything
   else sits at caption weight, because the rest of the show is
   context and the reader is not in it.
   ------------------------------------------------------------ */

.oyss .runorder {
  margin-top: clamp(26px, 3.4vw, 44px);
  max-width: 48rem;
  border-top: 1px solid rgba(228, 218, 214, .15);
}
.oyss .runrow {
  display: grid;
  grid-template-columns: 9.25rem 1fr;
  gap: clamp(14px, 2vw, 26px);
  padding: 1.05rem 0 1.05rem 1.1rem;
  border-bottom: 1px solid rgba(228, 218, 214, .15);
  position: relative;
}
.oyss .runrow__t {
  font-size: var(--t-caption); letter-spacing: .12em; text-transform: uppercase;
  color: var(--ivory-46); padding-top: .18em;
  font-variant-numeric: tabular-nums;
}
.oyss .runrow__what { font-size: 1.0625rem; line-height: 1.5; color: var(--ivory-70); }
.oyss .runrow__what span {
  display: block; margin-top: .18rem;
  font-size: var(--t-caption); color: var(--ivory-46);
}

/* The reader's own slot. A pool of key light down the left edge
   rather than a filled background, because the one motif is
   light and a filled row is a table cell. */
.oyss .runrow--you::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--rose);
  box-shadow: 0 0 26px 3px rgba(224, 90, 90, .34);
}
.oyss .runrow--you .runrow__t { color: var(--gold); }
.oyss .runrow--you .runrow__what { color: var(--ivory); font-weight: 700; }
.oyss .runrow--you .runrow__what span { color: var(--ivory-70); font-weight: 400; }
@media (max-width: 560px) {
  .oyss .runrow { grid-template-columns: 1fr; gap: .3rem; }
}

/* ---- 44.5 THE QUESTION INDEX --------------------------------
   Fourteen accordions in a column is a support page. The same
   fourteen with a standing index beside them is a document, and
   the index is the only thing on that page that tells a reader
   how long it is before they start opening things.
   ------------------------------------------------------------ */

.oyss .qadoc {
  display: grid;
  grid-template-columns: 15rem 1fr;
  gap: clamp(28px, 5vw, 84px);
  align-items: start;
}
.oyss .qaindex { position: sticky; top: calc(var(--oyss-mh, 78px) + 28px); }
.oyss .qaindex li { padding: .42rem 0; }
.oyss .qaindex a {
  font-size: var(--t-caption); line-height: 1.4; color: var(--slate);
  border-bottom: 1px solid transparent;
}
.oyss .qaindex a:hover { color: var(--red); border-bottom-color: var(--red); }
.oyss .qaindex__n {
  display: block; margin: 1.5rem 0 .4rem;
  font-size: var(--t-eyebrow); font-weight: 600; letter-spacing: .24em;
  text-transform: uppercase; color: var(--red);
}
.oyss .qaindex li:first-child .qaindex__n { margin-top: 0; }
.oyss .qaindex__count {
  margin-top: 1.8rem; padding-top: 1rem;
  border-top: 1px solid rgba(31, 30, 29, .14);
  font-size: var(--t-caption); line-height: 1.5; color: var(--slate);
}
@media (max-width: 900px) {
  .oyss .qadoc { grid-template-columns: 1fr; }
  .oyss .qaindex { display: none; }
}

/* ---- 44.6 THE PAIR ------------------------------------------
   One shape that is allowed to break the column on the interior
   pages, so a reader scrolling any of them meets a change of
   scale at least once. Two photographs at unequal widths, the
   narrower one held down the page. It is the showcase's idea at
   a quarter of its markup, and it is what actually answers "only
   the homepage is looking": those pages had one picture each.
   ------------------------------------------------------------ */

.oyss .pair {
  display: grid;
  grid-template-columns: 1.55fr 1fr;
  gap: clamp(18px, 2.4vw, 34px);
  align-items: start;
  margin-top: clamp(34px, 4.6vw, 64px);
}
.oyss .pair figure { margin: 0; }
.oyss .pair figure:last-child { margin-top: clamp(30px, 5vw, 78px); }
.oyss .pair img { width: 100%; height: auto; display: block; }
.oyss .pair figcaption {
  margin-top: .85rem;
  font-size: var(--t-caption); line-height: 1.5; color: var(--slate);
  max-width: 34rem;
}
.oyss .dark .pair figcaption, .oyss .stage .pair figcaption { color: var(--ivory-46); }
@media (max-width: 720px) {
  .oyss .pair { grid-template-columns: 1fr; }
  .oyss .pair figure:last-child { margin-top: 0; }
}

/* ---- 44.7 THE PAGE CLOSE ------------------------------------
   Every interior page ended on the same object: a centered
   display headline, a pool and two buttons. Five pages closing
   identically is the last place the template shows, and it is
   also the least useful, because the right next step is not the
   same on a page about panelists as it is on a page about a
   three thousand dollar engagement.

   So the close is a rule, one line naming what happens next on
   THIS page, and one action. The home page keeps its flood;
   nothing else does.

   Feedback 6.0: "This apply panelist button is not looking
   nice." It was a two column grid of [statement + detail | one
   button] aligned to the bottom, so on a wide screen the button
   sat alone at the far right with a hundred pixels of nothing
   above it, anchored to no sentence. Now the statement holds the
   left and the detail and its action share the right, top
   aligned, so the button sits under the sentence that explains
   it. Markup: .close__t then .close__aside (.close__m + .actions).
   ------------------------------------------------------------ */

.oyss .close {
  border-top: 1px solid rgba(31, 30, 29, .14);
  padding-top: clamp(30px, 4vw, 52px);
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(24px, 5vw, 88px);
  align-items: start;
}
.oyss .dark .close, .oyss .stage .close { border-top-color: rgba(228, 218, 214, .16); }
.oyss .close__t {
  font-family: var(--serif); font-weight: 700;
  font-size: clamp(1.4rem, 1rem + 1.6vw, 2.05rem);
  line-height: 1.2; letter-spacing: -.01em;
  max-width: 22ch; color: var(--ink);
  text-wrap: balance;
}
.oyss .dark .close__t, .oyss .stage .close__t { color: var(--ivory); }
.oyss .close__aside { padding-top: .3em; }
.oyss .close__m {
  max-width: 44ch;
  font-size: var(--t-caption); line-height: 1.55; color: var(--slate);
}
.oyss .dark .close__m, .oyss .stage .close__m { color: var(--ivory-46); }
.oyss .close__aside .actions { margin-top: 1.5rem; }
@media (max-width: 720px) {
  .oyss .close { grid-template-columns: 1fr; gap: 0; }
  .oyss .close__aside { padding-top: .9rem; }
}

/* ---- 44.8 THE FRAME DEMO ON A LIGHT GROUND ------------------
   The panelist frame used to sit on the dark stage band. That
   band is now the run of show, and two dark sections in a row is
   the metronome problem again, so the demo moved onto paper.
   Its step labels were written for ivory on charcoal and went to
   3:1 on white. The frame itself is a photograph and stays dark;
   only the labels under it change context.
   ------------------------------------------------------------ */

.oyss .paper .build__step, .oyss .light .build__step { color: var(--slate); }
.oyss .paper .build__step::before,
.oyss .light .build__step::before { background: rgba(31, 30, 29, .22); }
.oyss .paper .build__step.on, .oyss .light .build__step.on { color: var(--ink); }
.oyss .paper .build__step.on::before,
.oyss .light .build__step.on::before { background: var(--red); }

/* ---- 44.9 THE COUNTER THAT APPEARED TWICE -------------------
   "A random number 2 is showing up, please fix it" was one of
   two notes about a number nobody could place. This is the other
   one, found while looking for it: on the assessment the stepper
   builds its own "Question 1 of 8" bar, and the section label it
   moves into the pane says the same thing again, two lines
   apart.

   The label's copy is the no-JavaScript path and has to stay in
   the markup, so it is hidden once the stepper has actually
   built itself. .quiz is set by the stepper, not by the page, so
   with JS off both the eight questions and their numbering are
   still there.
   ------------------------------------------------------------ */

.oyss .qnum {
  font-size: .6875rem;
  color: var(--slate);
  letter-spacing: .16em;
  margin-left: auto;
}
.oyss .quiz .qnum { display: none; }


/* ============================================================
   45. FEEDBACK 4.0
   ------------------------------------------------------------
   Ten notes. Most of them are subtractions or new photography
   and live in the pages themselves; these are the two that are
   stylesheet bugs.
   ============================================================ */

/* ---- 45.1 THE SHEET NEVER ACTUALLY OVERLAPPED ---------------
   note 8   "Start the form like this"      (assessment)
   note 10  "Make sure the form overlaps the black above the
             fold section"                  (apply)

   Both screenshots draw a box from inside the dark band down
   over the top of the white form. The form was ALREADY built to
   do that: `.sheet` carries margin-top: -84px so it lifts out of
   whatever is above it. Measured on the page, it was not doing
   it, and the reason is margin collapse.

   The sheet is the first in-flow child of `.sheetbay`, and
   neither the section nor the `.wrap` between them establishes a
   block formatting context. So the negative margin collapsed
   through both and moved THE SECTION up instead of moving the
   sheet out of it. Apply.html measured section top 463 and sheet
   top 463: identical. The section carries the light background,
   so it painted Warm Neutral over the bottom 82px of the dark
   hero and the overlap was invisible, every time, on all three
   form pages.

   `display: flow-root` stops the collapse. The section now
   starts where the dark band ends and keeps its own background
   there, and the sheet lifts out over the dark on its own.
   Nothing else moves: the same 82px comes off the section's
   height either way.
   ------------------------------------------------------------ */

.oyss .sheetbay { display: flow-root; }

/* The hero above a lifted sheet has to give that height back, or
   the sheet covers its last line. This is the same bug round 5
   fixed by hand on apply.html, and raising the lift brings it
   straight back on all three form pages, so it is a rule now
   rather than one page's padding.

   Feedback 5.0, note 1: "The form is overlapping the text". It
   was, on the assessment, because that section carried an inline
   padding-bottom that beat this rule and happened to be smaller
   than the lift. Two changes: the inline style is gone, and the
   padding is now derived from the lift plus a fixed gap instead
   of being a separate number that has to be remembered whenever
   the lift changes. --sheet-lift is the single source. */
.oyss { --sheet-lift: clamp(56px, 8vw, 118px); }
.oyss .sheetbay .sheet { margin-top: calc(-1 * var(--sheet-lift)); }
.oyss .reel--short:has(+ .sheetbay),
.oyss .bay--half.dark:has(+ .sheetbay) {
  padding-bottom: calc(var(--sheet-lift) + clamp(28px, 4vw, 52px));
}

@media (max-width: 720px) {
  /* On a phone the hero stacks and the picture sits under the
     type, so there is much less to lift out of. Only the one
     number moves; the padding follows it. */
  .oyss { --sheet-lift: clamp(28px, 6vw, 48px); }
}

/* ---- 45.2 A WIDE FIGURE THAT HOLDS A VIDEO ------------------
   note 3  "Add the video here that I will be sharing it with
            you"

   `.figure-wide` was built for a photograph: the image fills it
   and the caption is laid over the bottom on a gradient. A video
   with a control bar cannot take an overlaid caption, because
   the caption lands exactly where the scrubber is. So this
   variant drops the overlay and sets the caption under the
   picture instead. Everything else about the figure is unchanged.
   ------------------------------------------------------------ */

.oyss .figure-wide video { width: 100%; height: auto; display: block; background: #0D0C0C; }
.oyss .figure-wide--video { border: 0; background: none; }
.oyss .figure-wide--video video { border: 1px solid rgba(31, 30, 29, .14); }
.oyss .dark .figure-wide--video video,
.oyss .stage .figure-wide--video video { border-color: rgba(228, 218, 214, .16); }
.oyss .figure-wide--video figcaption {
  position: static;
  padding: .95rem 0 0;
  background: none;
  color: var(--slate);
  max-width: 46rem;
}
.oyss .dark .figure-wide--video figcaption,
.oyss .stage .figure-wide--video figcaption { color: var(--ivory-46); }

/* ============================================================
   46. FEEDBACK 5.0
   ============================================================ */

/* ---- 46.1 THE RIG, ON A PHONE -------------------------------
   note 5  "The panelist section is not looking on mobile can you
            make it in such a way that it looks good mobile too
            how it looking on desktop"

   It was collapsing to two columns at 760 and to ONE at 420, so
   a phone got six full width photographs stacked down the page.
   That is not the component: the component is one host frame
   with five satellites around it, and the composition is the
   thing that says produced multi camera panel rather than six
   headshots.

   So the desktop grid is kept all the way down. What changes is
   everything that cannot survive a 110px tile: the nameplate on
   the five satellites drops to the role line alone, the ON AIR
   marker and the mark shrink with it, and the host frame keeps
   its full plate because it is the one tile with room.
   ------------------------------------------------------------ */

@media (max-width: 760px) {
  .oyss .rig { grid-template-columns: repeat(3, 1fr); gap: 6px; }
  .oyss .frame--host { grid-column: span 2; grid-row: span 2; }
  .oyss .frame { padding: 6px; }
  .oyss .frame--host { padding: 10px; }

  /* The five satellites. At this size a two line nameplate is
     four illegible words in a box, so the box goes and the role
     stays, which is the part that carries the meaning. */
  .oyss .frame:not(.frame--host) .frame__plate {
    background: none; backdrop-filter: none;
    border-left-width: 1px;
    padding: .18rem .3rem;
  }
  .oyss .frame:not(.frame--host) .frame__role { font-size: .4375rem; letter-spacing: .16em; }
  .oyss .frame:not(.frame--host) .frame__name,
  .oyss .frame:not(.frame--host) .frame__sub { display: none; }
  .oyss .frame:not(.frame--host) .frame__live {
    top: 5px; right: 5px; padding: .1rem .26rem;
    font-size: .4375rem; letter-spacing: .12em; gap: .22rem;
  }
  .oyss .frame:not(.frame--host) .frame__live::before { width: 3px; height: 3px; }
  .oyss .frame:not(.frame--host) .frame__mark { transform: scale(.72); transform-origin: left top; }

  /* The host tile is two thirds of the width and holds its plate. */
  .oyss .frame--host .frame__name { font-size: 1rem; }
  .oyss .frame--host .frame__role { font-size: .5rem; }
  .oyss .frame--host .frame__sub  { font-size: .5625rem; }

  /* The host tile is 230px wide on a 390px phone, and the lockup
     plus the ON AIR marker do not both fit across it: the
     wordmark ran under the badge. The mark keeps its glyph,
     which is the part that brands the frame, and drops the
     words, exactly as the five satellites already do. */
  .oyss .rig--live .frame--host .frame__mark b { display: none; }
  .oyss .rig--live .frame--host .frame__mark svg { width: 18px; height: 18px; }
  .oyss .rig--live .frame--host .frame__live {
    right: 8px; top: 7px; padding: .16rem .36rem;
    font-size: .5rem; letter-spacing: .14em;
  }
}

/* The 420 rule that stacked them is gone; these keep their
   aspect ratio instead, so the composition holds on a small
   phone rather than turning into a column. */
@media (max-width: 420px) {
  .oyss .rig { gap: 4px; }
  .oyss .frame--host .frame__name { font-size: .9rem; }
}

/* ---- 46.2 THE FILM SECTION ----------------------------------
   note 4  "This one should be a proper section with headings and
            everything as this is one section which explain what
            own your stage studio is about. You could create a
            thumbnail too for the video if you wanted... Create it
            beautifully for mobile and tablet version"

   The head is a two column split on a desktop, so the heading
   and the sentence under it sit side by side rather than in one
   tall stack above a wide picture. It collapses at 860, which is
   where every other split on the site collapses.
   ------------------------------------------------------------ */

.oyss .filmhead {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: clamp(20px, 4vw, 64px);
  align-items: end;
}
.oyss .filmhead .lead { margin: 0; max-width: 38rem; }
@media (max-width: 860px) {
  .oyss .filmhead { grid-template-columns: 1fr; align-items: start; }
  .oyss .filmhead .lead { margin-top: 1.1rem; }
}

/* The picture. A 16:9 box so the poster and the film are the
   same shape and nothing jumps when it starts. */
.oyss .videoblock {
  position: relative;
  margin-top: clamp(26px, 3.6vw, 48px);
  border: 1px solid rgba(31, 30, 29, .14);
  background: #0D0C0C;
  aspect-ratio: 16 / 9;
  overflow: hidden;
}
.oyss .videoblock video {
  width: 100%; height: 100%; display: block;
  object-fit: cover;
  background: #0D0C0C;
}

/* The play control. Chrome's native one on a poster frame is a
   small triangle in the bottom corner, which reads as a still
   image with a toolbar rather than as a film. This is the whole
   picture: click anywhere. It removes itself on play and the
   native controls take over from there. */
.oyss .videoblock__play {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  gap: clamp(12px, 1.6vw, 20px);
  border: 0; cursor: pointer;
  background: linear-gradient(180deg, rgba(19, 18, 17, .46) 0%, rgba(19, 18, 17, .30) 42%,
                                      rgba(19, 18, 17, .62) 100%);
  color: var(--ivory);
  transition: background 320ms var(--settle);
  padding: 0;
}
.oyss .videoblock__play:hover { background: rgba(19, 18, 17, .40); }
.oyss .videoblock.is-playing .videoblock__play { display: none; }

.oyss .videoblock__ico {
  flex: none;
  width: clamp(54px, 5.4vw, 76px); aspect-ratio: 1;
  border-radius: 50%;
  background: var(--red);
  display: grid; place-items: center;
  box-shadow: 0 18px 44px -18px rgba(185, 28, 28, .8);
  transition: transform 320ms var(--settle);
}
.oyss .videoblock__play:hover .videoblock__ico { transform: scale(1.06); }
/* The triangle, drawn rather than typed, so it is centered on
   the optical middle of the disc and not on the glyph box. */
.oyss .videoblock__ico::before {
  content: '';
  width: 0; height: 0;
  margin-left: .18em;
  border-left: clamp(15px, 1.5vw, 21px) solid var(--ivory);
  border-top: clamp(10px, 1vw, 14px) solid transparent;
  border-bottom: clamp(10px, 1vw, 14px) solid transparent;
}
.oyss .videoblock__label {
  text-align: left;
  font-family: var(--serif); font-weight: 700;
  font-size: clamp(1.05rem, .85rem + .7vw, 1.45rem);
  line-height: 1.2;
  text-shadow: 0 2px 22px rgba(19, 18, 17, .7);
}
/* Ivory, not gold. The poster is whatever frame the film opens
   on, and this one is pale, so a gold caption measured 2.4:1 on
   it. The scrim below carries both lines instead. */
.oyss .videoblock__label b {
  display: block;
  margin-top: .34rem;
  font-family: var(--sans); font-weight: 600;
  font-size: var(--t-eyebrow); letter-spacing: .2em; text-transform: uppercase;
  color: var(--ivory);
  text-shadow: 0 2px 18px rgba(19, 18, 17, .9);
}
.oyss .videoblock__note { margin-top: .95rem; color: var(--slate); }

/* Phone and tablet. The label goes under the disc so the control
   stays inside a 16:9 box that is only 350px wide, and the disc
   comes down with it. */
@media (max-width: 620px) {
  .oyss .videoblock__play { flex-direction: column; gap: .8rem; }
  .oyss .videoblock__label { text-align: center; }
  .oyss .videoblock__ico { width: 52px; }
}

/* ---- 46.3 THE APPLICATION, STEPPED --------------------------
   note 2  "Make the apply.html form similar to the
            assessment.html form style"

   The chrome is the assessment's, reused class for class, so the
   two forms are one family. What this adds is the part the
   assessment does not need: a Continue button, because a form
   full of text fields cannot auto advance on a click the way a
   form full of radios can.
   ------------------------------------------------------------ */

.oyss .quiz--form .qstep .sheet__sec { margin-top: 0; }
.oyss .quiz__nav--form {
  display: flex; align-items: center; gap: clamp(14px, 2vw, 24px);
  flex-wrap: wrap;
  margin-top: clamp(22px, 3vw, 34px);
}
/* Back sits to the LEFT of Continue and stays quiet, because the
   forward action is the one being offered. */
.oyss .quiz__nav--form .quiz__back { order: 0; }
.oyss .quiz__next { order: 1; }
.oyss .quiz__nav--form .quiz__hint { order: 2; color: #B91C1C; }

@media (max-width: 520px) {
  .oyss .quiz__nav--form { gap: .9rem; }
  .oyss .quiz__next { width: 100%; order: 0; justify-content: center; }
  .oyss .quiz__nav--form .quiz__back { order: 1; }
  .oyss .quiz__nav--form .quiz__hint { order: 2; width: 100%; }
}

/* ---- 46.4 THE DESKTOP RHYTHM, TIGHTENED ---------------------
   "site feels a bit heavy on desktop"

   Measured before touching anything, at 1440x900: the home page
   ran 12,303px, which is 13.7 screens, and about 2,000px of that
   is section padding.

   The interesting number was not the total, it was the
   comparison. Below 1041px the site already sets
   --bay: clamp(62px, 8vw, 104px), and above it the same token is
   clamp(72px, 9vw, 132px). A desktop was being given 27 percent
   MORE air per section than a tablet, on a viewport that is
   wider and therefore already reads as roomier. That is the
   asymmetry behind "heavy on desktop" and it was never a
   decision, only two clamps written months apart.

   So the whole ladder scales down and the ratios that section 41
   set on purpose are kept intact:

                  before (1440)   after   ratio to --bay
     .bay--open       190          152         1.51 -> 1.51
     .bay             130          104         1.00 -> 1.00
     .bay--tight       72           58          .56 ->  .56
     .essay           168          132         1.29 -> 1.27

   Nothing is restructured, no section is removed, no type moves.
   ------------------------------------------------------------ */

@media (min-width: 1041px) {
  .oyss { --bay: clamp(72px, 7.2vw, 104px); }
  .oyss .bay--open  { padding: clamp(104px, 10.6vw, 152px) 0; }
  .oyss .bay--tight { padding: clamp(44px, 4vw, 58px) 0; }
  .oyss .essay      { padding: clamp(88px, 9.2vw, 132px) 0; }
  .oyss .band__copy {
    padding-block: clamp(56px, 7vw, 92px) clamp(38px, 4.4vw, 56px);
  }
}


/* ============================================================
   47. THE WIDE SCREEN  (feedback 6.0)
   ------------------------------------------------------------
   "See the site is screen responsive also, I opened the site on
    another laptop and the title and everything looks very
    contained. The same issue is with all the pages."

   Measured before touching anything. The site was designed and
   approved at 1440 and it held there. Above that it stopped
   responding: the wrap is capped at 1180px, every display size
   is a clamp whose top is reached by 1240px, and the hero copy
   column was a fixed 48rem box whose left padding grows with the
   viewport, so the TEXT inside it got narrower as the screen got
   wider. On a 1536 laptop (a 1080p screen at 125%) the headline
   ran five lines in 482px; at 1920 it ran seven lines in 278px
   with 370px of dark on either side of everything else.

   Three things, all above 1440 so the approved layout is
   untouched below it:

     1. --wrap grows with the viewport, 86vw capped at 1640, so
        the content holds the same share of the screen it holds
        at 1440 instead of a shrinking one.
     2. The root font size eases from 100% at 1440 to 112.5% at
        1920 (in build.py's page shell, because it is the html
        element and this file must not style anything outside
        .oyss). Every rem measure on the site scales with it, so
        columns, leads and buttons grow together and the page
        reads as the same design, larger, rather than the same
        design with wider margins.
     3. The display sizes keep climbing instead of stopping at
        their 1240px cap.

   The hero copy column's box is gone entirely (section 29); the
   measure now lives on the headline and the lead, where it
   always should have.
   ============================================================ */

.oyss .reel .display { max-width: 14ch; }

@media (min-width: 1441px) {
  .oyss {
    --wrap: clamp(1180px, 86vw, 1640px);
    --t-display: clamp(4.5rem, 2.2rem + 2.6vw, 5rem);
    --t-heading: clamp(2.35rem, 1.1rem + 1.4vw, 2.75rem);
  }
  /* the home hero only: .reel--page and .reel--short set their own size
     at the same specificity, and this rule is later in the file */
  .oyss .reel--spot .display { font-size: clamp(4.2rem, 2rem + 2.4vw, 4.8rem); }
  .oyss .reel .lead { max-width: 32rem; }
}


/* ---- 47.2 THE FILM, AS THE SECTION THAT SELLS ----------------
   "This is lamely done, 'Play the film 2 min 2 sec', all these
    crappy wording, no real exciting copy done. This is the
    section which helps in converting majority of the people."

   The film is the studio's own two minute pitch and it sat on
   the page as a labelled object: a neutral heading, a duration
   and a note about captions. Nothing on it asked anyone to press
   play, and nothing after it asked anyone to do anything.

   Now it is built like the thing it is. The head makes the case
   for pressing play. The run order under the picture names the
   film's own six chapters, in its own words, and each one starts
   the film at that point, so a reader who will not sit through
   two minutes can go straight to the night, or to what they
   keep. And the section closes with the next step, because the
   moment the film ends is the warmest a reader gets on this page.
   ------------------------------------------------------------ */

.oyss .videoblock__label { font-size: clamp(1.2rem, .9rem + .9vw, 1.7rem); }

.oyss .filmcues {
  margin-top: clamp(18px, 2.4vw, 30px);
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 0 clamp(14px, 1.8vw, 28px);
  border-top: 1px solid rgba(31, 30, 29, .14);
}
.oyss .filmcue {
  /* grid, not block: a button centers its content vertically by default,
     so a two line cue sat higher than a one line one */
  display: grid; align-content: start; justify-items: start;
  width: 100%;
  padding: 1rem 0 .3rem;
  border: 0; background: none; cursor: pointer;
  text-align: left; color: var(--ink);
  font: inherit;
  position: relative;
}
/* The rule above each cue is the marker: red on the cue that is
   playing, red on hover, and the rest a hairline. */
.oyss .filmcue::before {
  content: '';
  position: absolute; left: 0; right: 0; top: -1px;
  height: 3px; background: var(--red);
  transform: scaleX(0); transform-origin: left center;
  transition: transform 420ms var(--fade-up);
}
.oyss .filmcue:hover::before, .oyss .filmcue.on::before { transform: scaleX(1); }
.oyss .filmcue__t {
  display: block;
  font-family: var(--serif); font-weight: 600;
  font-size: var(--t-eyebrow); letter-spacing: .16em; text-transform: uppercase;
  color: var(--red);
  font-variant-numeric: tabular-nums;
}
.oyss .filmcue__n {
  display: block; margin-top: .3rem;
  font-family: var(--serif); font-weight: 700;
  font-size: 1rem; line-height: 1.25; letter-spacing: -.005em;
}
.oyss .filmcue:hover .filmcue__n, .oyss .filmcue.on .filmcue__n { color: var(--red); }
.oyss .filmcue:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; }
.oyss .filmcues__hint { margin-top: .9rem; color: var(--slate); }

.oyss #film .close { margin-top: clamp(40px, 5vw, 72px); }

@media (max-width: 900px) {
  .oyss .filmcues { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .oyss .filmcue { padding-bottom: .8rem; }
  /* rows two and three need their own rule to hang the marker from */
  .oyss .filmcue:nth-child(n+4) { border-top: 1px solid rgba(31, 30, 29, .14); }
}
@media (max-width: 520px) {
  .oyss .filmcues { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 clamp(14px, 4vw, 22px); }
  .oyss .filmcue:nth-child(n+3) { border-top: 1px solid rgba(31, 30, 29, .14); }
}
