/* ═══════════════════════════════════════════════════════════════════════════
   CLIPD CUT DESK — the shared layer
   Loaded by the landing and by the signed-in app, in that order, before each
   surface's own stylesheet overrides. Everything here is either a token or a
   component that both surfaces use, so the two never drift apart again.

   THE COLOUR RULE (magenta, 2026-08-07 — it governs every rule below)
   Magenta is Clipd: money, primary actions, the selected cut and verified state.
   Cyan is views, reach and tracking, and the focus ring. Violet is levels.
   Amber is pending, red is rejected. Everything else is graphite.
   Lime is gone. It meant money AND the selected cut AND the primary action at
   once, so it ended up on the skip link, the HUD and every button — and a dark
   page with a green accent is what every other clipping platform looks like.
   Magenta was measured against all five remaining semantics before it was
   chosen; the nearest is `--cd-bad` at ΔE 0.100, comfortably apart.
   ═══════════════════════════════════════════════════════════════════════════ */

:root{
  /* — canvas — */
  --cd-void:#090809;
  --cd-panel:#120F11;
  --cd-panel-2:#1A1619;
  --cd-ink:#F7F8F8;
  --cd-dim:#A9A9AA;
  --cd-faint:#8D898C;
  --cd-line:rgba(255,255,255,.13);
  --cd-line-hard:rgba(255,255,255,.26);

  /* — semantics —
     One brand colour for money, action, the selected cut and verified states.
     Focus rings and tracked-view signals stay cyan; levels stay violet;
     warnings and errors keep amber/red. Everything else stays carbon. */
  --cd-brand:#FF4D9D;          /* the one Clipd colour */
  --cd-brand-ink:#0C0C0C;      /* text on top of it */
  --cd-money:var(--cd-brand);  /* amounts, balance, budget, payout, rate */
  --cd-money-ink:var(--cd-brand-ink);
  --cd-action:var(--cd-brand); /* primary action surface */
  --cd-action-ink:var(--cd-brand-ink);
  /* --cd-cut and --cd-ok were both pointed at --cd-brand. That collapses the
     palette: the playhead, the cut marker and every "verified" state became
     the same magenta as the amounts, so the brand colour stopped meaning
     anything and every rule that tried to separate them silently resolved
     back to magenta. A semantic token that aliases the brand colour is not a
     semantic token. */
  --cd-cut:#F7F8F8;            /* the playhead and the cut marker: "where you are" */
  --cd-focus:#79E7FF;          /* focus ring — a system colour, never a brand one */
  --cd-signal:#79E7FF;         /* views · reach · tracking */
  --cd-level:#A78BFA;          /* levels · progression */
  --cd-ok:#4ADE80;             /* approved · verified */
  --cd-warn:#FFC857;           /* pending · attention */
  --cd-bad:#FF5C5C;            /* rejected · error */

  /* — the 4 / 10 / 16 radius system. Technical parts stay square. — */
  --cd-r-chip:4px;
  --cd-r:10px;
  --cd-r-lg:16px;

  --cd-mono:"JetBrains Mono",ui-monospace,SFMono-Regular,monospace;
  --cd-display:"Space Grotesk",Inter,sans-serif;
  --cd-body:Inter,system-ui,sans-serif;
  --cd-ease:cubic-bezier(.2,.8,.2,1);
  --cd-snap:cubic-bezier(.16,1,.3,1);
}

/* Background direction 03 — Midnight Drift.
   One fixed composited light field sits behind both the landing and the app.
   The large inset keeps its edges outside the viewport while it moves. */
body.clipd-midnight-canvas{
  isolation:isolate;
}
body.clipd-midnight-canvas::before{
  content:"";
  position:fixed;
  inset:-35%;
  z-index:-1;
  pointer-events:none;
  background:linear-gradient(
    115deg,
    transparent 32%,
    rgba(255,77,157,.03) 40%,
    rgba(255,77,157,.14) 49%,
    rgba(255,77,157,.04) 58%,
    transparent 68%
  );
  opacity:.48;
  transform:translate3d(-14%,0,0) skewX(-6deg);
  animation:cd-midnight-drift 12s ease-in-out infinite alternate;
  will-change:transform,opacity;
}
@keyframes cd-midnight-drift{
  from{opacity:.3;transform:translate3d(-14%,0,0) skewX(-6deg)}
  to{opacity:.82;transform:translate3d(14%,0,0) skewX(-6deg)}
}
@media(prefers-reduced-motion:reduce){
  body.clipd-midnight-canvas::before{
    animation:none;
    opacity:.55;
    transform:none;
  }
}

/* The UA rule `[hidden]{display:none}` loses to any author rule that sets
   `display` at the same specificity — `.cd-field{display:flex}` was quietly
   keeping the sign-up name field on screen during sign-in. Hidden means
   hidden. */
[hidden]{display:none!important}

/* Utility: a tape label. Used wherever something needs to be marked as an
   example, a status, or a lane name without becoming another card. */
.cd-tape{
  display:inline-flex;
  align-items:center;
  gap:6px;
  padding:3px 8px;
  border-radius:var(--cd-r-chip);
  background:rgba(255,255,255,.07);
  color:var(--cd-faint);
  font-family:var(--cd-mono);
  font-size:10px;
  font-weight:600;
  letter-spacing:.14em;
  text-transform:uppercase;
  white-space:nowrap;
}
.cd-tape--example{
  background:rgba(255,200,87,.1);
  color:var(--cd-warn);
  box-shadow:inset 0 0 0 1px rgba(255,200,87,.28);
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE LIVING CLIPD ENGINE
   A timeline, not a dashboard. Rails and lanes carry the structure; there is
   no outer card, and the source deliberately runs past its own frame.
   ═══════════════════════════════════════════════════════════════════════════ */

.cde{
  --cde-head:3%;
  --cde-lock-l:38%;
  --cde-lock-r:52%;
  /* The 9:16 crop is derived from its height, in one place. `aspect-ratio`
     alone loses against a stretching flex/grid cross-axis and silently turns
     the frame landscape — the one shape an output must never be. */
  --cde-frame-h:clamp(122px,21vh,206px);
  --cde-frame-w:calc(var(--cde-frame-h) * .5625);
  --cde-gap:clamp(8px,1.4vw,16px);
  /* Three crops side by side, never wider. The wide source narrowing to three
     vertical outputs and then to one balance is the whole shape of the loop —
     stretching the outputs across the full column would flatten it. */
  --cde-out-w:calc(var(--cde-frame-w) * 3 + var(--cde-gap) * 2);
  position:relative;
  display:grid;
  grid-auto-rows:auto;
  align-content:center;
  gap:clamp(12px,1.7vh,20px);
  width:100%;
  min-width:0;
  color:var(--cd-ink);
  font-family:var(--cd-body);
}

/* — the ruler: timecodes and edit marks, the page as a timeline — */
.cde__ruler{
  position:relative;
  display:flex;
  align-items:flex-end;
  justify-content:space-between;
  height:22px;
  padding-bottom:5px;
  border-bottom:1px solid var(--cd-line);
  font-family:var(--cd-mono);
  font-size:9px;
  font-weight:600;
  letter-spacing:.12em;
  color:var(--cd-faint);
}
.cde__ruler span{position:relative;padding-left:5px}
.cde__ruler span::before{
  content:"";
  position:absolute;
  left:0;
  bottom:-6px;
  width:1px;
  height:9px;
  background:var(--cd-line-hard);
}

/* — lane headers — */
.cde__lane-head{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:12px;
  font-family:var(--cd-mono);
  font-size:10px;
  font-weight:600;
  letter-spacing:.15em;
  text-transform:uppercase;
  color:var(--cd-faint);
}
.cde__lane-head b{color:var(--cd-dim);font-weight:600}

/* — SOURCE: a long strip that travels through the composition — */
.cde__source{
  position:relative;
  height:clamp(96px,13vh,132px);
  /* The strip is wider than the lane and is allowed to run out of it on both
     sides — the source is longer than the frame you are looking at. */
  overflow:hidden;
  border-block:1px solid var(--cd-line);
  background:
    repeating-linear-gradient(90deg,rgba(255,255,255,.045) 0 1px,transparent 1px 42px),
    var(--cd-panel);
}
.cde__film{
  position:absolute;
  inset:14px -18% 14px -18%;
  display:flex;
  gap:4px;
  transform:translate3d(-9%,0,0);
  transition:transform 1.5s var(--cd-ease);
}
.cde.is-scanning .cde__film{transform:translate3d(0,0,0)}
.cde__film i{
  position:relative;
  flex:1 1 0;
  min-width:0;
  border-radius:4px;
  background:linear-gradient(168deg,#272226,#181316 68%);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.07);
  opacity:.62;
  transition:opacity .45s var(--cd-ease),filter .45s var(--cd-ease),transform .45s var(--cd-snap);
}
/* Sprocket holes down each frame: this is film, not a chart. */
.cde__film i::after{
  content:"";
  position:absolute;
  inset:auto 4px 3px 4px;
  height:2px;
  background:repeating-linear-gradient(90deg,rgba(255,255,255,.22) 0 2px,transparent 2px 7px);
}
/* The moment. It lights up white once it has actually been selected — the
   same colour as the playhead, because both answer "where is the cut?". */
.cde__film i.is-hot{background:linear-gradient(168deg,#321E2B,#21131B 70%)}
.cde.is-locked .cde__film i.is-hot{
  opacity:1;
  box-shadow:inset 0 0 0 1px rgba(247,248,248,.5),0 0 24px -6px rgba(247,248,248,.32);
}
/* The hard cut: everything that is not the moment falls away. */
.cde.is-cut .cde__film i:not(.is-hot){opacity:.13;filter:grayscale(1)}
.cde.is-cut .cde__film i.is-hot{transform:scaleY(1.1)}
.cde.is-split .cde__film i.is-hot{opacity:.25;transform:scaleY(.86)}

/* — the playhead — */
.cde__head{
  position:absolute;
  top:0;
  bottom:0;
  left:var(--cde-head);
  width:2px;
  background:var(--cd-cut);
  box-shadow:0 0 18px rgba(247,248,248,.55);
  transition:left 1.85s linear,opacity .4s;
  z-index:3;
}
.cde__head::before{
  content:"";
  position:absolute;
  top:0;
  left:-4px;
  border-left:5px solid transparent;
  border-right:5px solid transparent;
  border-top:6px solid var(--cd-cut);
}
.cde.is-scanning{--cde-head:45%}
.cde.is-split .cde__head{opacity:0}

/* — crop marks: four corners that snap onto the chosen moment — */
.cde__lock{
  position:absolute;
  top:6px;
  bottom:6px;
  left:var(--cde-lock-l);
  right:calc(100% - var(--cde-lock-r));
  opacity:0;
  transform:scale(1.35);
  transition:opacity .3s,transform .42s var(--cd-snap);
  pointer-events:none;
  z-index:2;
}
.cde.is-locked .cde__lock{opacity:1;transform:none}
.cde.is-split .cde__lock{opacity:0;transform:scale(.9)}
.cde__lock b{position:absolute;width:11px;height:11px;border:1px solid var(--cd-cut)}
.cde__lock b:nth-child(1){top:0;left:0;border-width:1px 0 0 1px}
.cde__lock b:nth-child(2){top:0;right:0;border-width:1px 1px 0 0}
.cde__lock b:nth-child(3){bottom:0;left:0;border-width:0 0 1px 1px}
.cde__lock b:nth-child(4){bottom:0;right:0;border-width:0 1px 1px 0}
.cde__lock em{
  position:absolute;
  top:-9px;
  left:50%;
  transform:translateX(-50%);
  padding:1px 6px;
  background:var(--cd-cut);
  color:var(--cd-action-ink);
  font-family:var(--cd-mono);
  font-size:9px;
  font-style:normal;
  font-weight:700;
  letter-spacing:.1em;
  white-space:nowrap;
}

/* — OUTPUTS: the segment becomes three 9:16 frames — */
.cde__outputs{
  display:grid;
  grid-template-columns:repeat(3,var(--cde-frame-w));
  gap:var(--cde-gap);
  width:var(--cde-out-w);
  margin-inline:auto;
  align-content:start;
}
.cde__out{
  --cde-from:0%;
  position:relative;
  display:flex;
  flex-direction:column;
  gap:9px;
}
.cde__out:nth-child(1){--cde-from:96%}
.cde__out:nth-child(3){--cde-from:-96%}

/* The empty crop that is waiting to be filled. It is the composition at rest:
   three outputs are always the plan, even before the cut has been made. */
/* Height drives these boxes, never width: a 9:16 crop that gets clamped by
   max-height silently turns landscape, which is the one shape it must not be. */
.cde__slot{
  position:absolute;
  top:0;
  left:50%;
  height:var(--cde-frame-h);
  width:var(--cde-frame-w);
  transform:translateX(-50%);
  border:1px dashed var(--cd-line);
  border-radius:var(--cd-r-chip);
  opacity:1;
  transition:opacity .35s var(--cd-ease);
}
.cde.is-split .cde__slot{opacity:0}

.cde__live{
  display:flex;
  opacity:0;
  transform:translate3d(var(--cde-from),-96px,0) scale(.3);
  transition:opacity .4s var(--cd-ease),transform .78s var(--cd-snap);
}
.cde.is-split .cde__live{opacity:1;transform:translate3d(var(--cde-from),-34px,0) scale(.52)}
.cde.is-out .cde__live{transform:none}
.cde.is-split .cde__out:nth-child(2) .cde__live{transition-delay:.06s}
.cde.is-split .cde__out:nth-child(3) .cde__live{transition-delay:.12s}

/* The 9:16 frame itself — a crop, not a video player. No play button, no
   fake thumbnail: it is the shape of the output and the platform it is for. */
.cde__frame{
  position:relative;
  flex:0 0 auto;
  height:var(--cde-frame-h);
  width:var(--cde-frame-w);
  align-self:center;
  border:1px solid var(--cd-line-hard);
  border-radius:var(--cd-r-chip);
  background:linear-gradient(172deg,#241A21,#120E11 74%);
  overflow:hidden;
}
/* The cut sits inside its crop as a bright band — the part that was kept. */
.cde__frame::before{
  content:"";
  position:absolute;
  inset:34% 0 34% 0;
  background:linear-gradient(180deg,rgba(247,248,248,.14),rgba(247,248,248,.02));
  border-block:1px solid rgba(247,248,248,.34);
}
.cde__frame b{
  position:absolute;
  top:5px;
  left:5px;
  font-family:var(--cd-mono);
  font-size:8px;
  font-weight:700;
  letter-spacing:.1em;
  color:var(--cd-dim);
}
.cde__frame em{
  position:absolute;
  top:5px;
  right:6px;
  font-family:var(--cd-mono);
  font-size:8px;
  font-style:normal;
  letter-spacing:.08em;
  color:var(--cd-faint);
}

/* — the verification gate every output has to pass —
     Stamped onto the crop rather than stacked under it: the gate is something
     that happens *to* the output, so it belongs on the same object. */
.cde__gate{
  position:absolute;
  left:4px;
  right:4px;
  bottom:9px;
  display:flex;
  align-items:center;
  justify-content:center;
  gap:4px;
  min-height:18px;
  padding:2px 4px;
  border:1px dashed rgba(255,200,87,.55);
  border-radius:var(--cd-r-chip);
  background:rgba(25,14,22,.85);
  color:var(--cd-warn);
  font-family:var(--cd-mono);
  font-size:8.5px;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
  transition:border-color .3s,background .3s,color .3s;
}
.cde__gate::before{content:"◌"}
.cde.is-verified .cde__gate{
  border-style:solid;
  border-color:rgba(255,77,157,.6);
  background:rgba(255,77,157,.1);
  color:var(--cd-ok);
}
.cde.is-verified .cde__gate::before{content:"✓"}
.cde.is-verified .cde__out:nth-child(2) .cde__gate{transition-delay:.14s}
.cde.is-verified .cde__out:nth-child(3) .cde__gate{transition-delay:.28s}

/* — the tracked signal. Cyan, and it cannot move before the gate is verified. — */
.cde__meter{
  position:absolute;
  left:0;
  right:0;
  bottom:0;
  height:3px;
  background:rgba(255,255,255,.09);
  overflow:hidden;
}
.cde__meter i{
  position:absolute;
  inset:0;
  border-radius:inherit;
  background:linear-gradient(90deg,rgba(121,231,255,.35),var(--cd-signal));
  transform:scaleX(0);
  transform-origin:left;
  transition:transform 1.5s var(--cd-ease);
}
.cde.is-counting .cde__meter i{transform:scaleX(1)}
.cde.is-counting .cde__out:nth-child(2) .cde__meter i{transition-delay:.2s}
.cde.is-counting .cde__out:nth-child(3) .cde__meter i{transition-delay:.4s}

/* The count and the platform share one line under the crop, so an output that
   has not been cut yet is just an empty frame with a name — not a stack of
   waiting chrome. */
.cde__foot{
  display:flex;
  flex-direction:column;
  gap:1px;
  min-height:34px;
  padding-top:4px;
  border-top:1px solid var(--cd-line);
}
.cde__count{
  font-family:var(--cd-display);
  font-size:clamp(15px,1.5vw,19px);
  font-weight:600;
  letter-spacing:-.03em;
  color:var(--cd-signal);
  font-variant-numeric:tabular-nums;
  opacity:0;
  transition:opacity .4s;
}
.cde.is-counting .cde__count{opacity:1}
.cde__foot small{
  font-family:var(--cd-mono);
  font-size:8.5px;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--cd-faint);
}

/* — the three signals converge into one balance — */
.cde__converge{
  position:relative;
  height:clamp(24px,4vh,40px);
  width:var(--cde-out-w);
  margin-inline:auto;
}
.cde__converge svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.cde__converge path{
  fill:none;
  stroke:var(--cd-signal);
  stroke-width:1;
  opacity:.75;
  stroke-dasharray:1;
  stroke-dashoffset:1;
  transition:stroke-dashoffset .7s var(--cd-ease);
  /* pathLength=1 on the element makes the dash maths resolution-independent */
}
.cde.is-earning .cde__converge path{stroke-dashoffset:0}
.cde.is-earning .cde__converge path:nth-child(2){transition-delay:.1s}
.cde.is-earning .cde__converge path:nth-child(3){transition-delay:.2s}

.cde__earn{
  display:flex;
  align-items:center;
  gap:clamp(12px,2vw,22px);
  padding:clamp(11px,1.6vh,16px) clamp(12px,1.8vw,20px);
  border:1px solid var(--cd-line);
  border-radius:var(--cd-r);
  background:var(--cd-panel);
  /* Not so faint that it reads as a disabled control while it waits. */
  opacity:.5;
  transition:opacity .5s var(--cd-ease),border-color .5s,background .5s;
}
.cde.is-earning .cde__earn{
  opacity:1;
  border-color:rgba(255,77,157,.32);
  background:linear-gradient(100deg,rgba(255,77,157,.07),var(--cd-panel) 62%);
}
.cde__earn div{display:flex;flex-direction:column;gap:3px;min-width:0}
.cde__earn small{
  font-family:var(--cd-mono);
  font-size:9px;
  font-weight:600;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--cd-faint);
}
.cde__earn b{
  font-family:var(--cd-display);
  font-size:clamp(21px,2.6vw,32px);
  font-weight:700;
  letter-spacing:-.045em;
  line-height:1;
  font-variant-numeric:tabular-nums;
}
.cde__earn .cde__views b{color:var(--cd-signal)}
.cde__earn .cde__balance b{color:var(--cd-money)}
.cde__arrow{
  flex:0 0 auto;
  color:var(--cd-faint);
  font-family:var(--cd-mono);
  font-size:15px;
  transition:color .5s,transform .5s var(--cd-snap);
}
.cde.is-earning .cde__arrow{color:var(--cd-money);transform:translateX(3px)}

/* — the HUD strip: phase, example label, timecode — */
.cde__hud{
  display:flex;
  align-items:center;
  gap:10px;
  padding-top:8px;
  border-top:1px solid var(--cd-line);
  font-family:var(--cd-mono);
  font-size:9.5px;
  font-weight:600;
  letter-spacing:.15em;
  text-transform:uppercase;
}
.cde__hud [data-cde-status]{color:var(--cd-ink);min-width:11ch}
.cde__hud i{
  flex:1;
  height:1px;
  background:repeating-linear-gradient(90deg,var(--cd-line-hard) 0 3px,transparent 3px 8px);
}
.cde__hud time{color:var(--cd-faint);font-variant-numeric:tabular-nums}

/* — reduced motion: a complete, still composition of the finished loop — */
@media(prefers-reduced-motion:reduce){
  .cde *,.cde *::before,.cde *::after{transition:none!important;animation:none!important}
}
.cde[data-cde-static] .cde__film{transform:none}
.cde[data-cde-static] .cde__head{opacity:0}
/* In the animated loop the discarded frames fading to 13% *is* the cut. In the
   still composition there is no before-and-after to compare it to, so they
   would just read as an empty box — keep the source legible instead. */
.cde[data-cde-static].is-cut .cde__film i:not(.is-hot){opacity:.32;filter:none}

/* ═══════════════════════════════════════════════════════════════════════════
   SHARED STATE PATTERNS
   Loading is never the empty state. An error always offers a way back.
   ═══════════════════════════════════════════════════════════════════════════ */

.cd-skel{display:flex;flex-direction:column;gap:10px;padding:4px 0}
.cd-skel i{
  display:block;
  height:13px;
  border-radius:var(--cd-r-chip);
  background:linear-gradient(90deg,rgba(255,255,255,.05),rgba(255,255,255,.11),rgba(255,255,255,.05));
  background-size:220% 100%;
  animation:cd-shimmer 1.5s linear infinite;
}
.cd-skel i:nth-child(2){width:72%}
.cd-skel i:nth-child(3){width:54%}
@keyframes cd-shimmer{to{background-position:-220% 0}}
@media(prefers-reduced-motion:reduce){.cd-skel i{animation:none}}

.cd-state{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:9px;
  padding:clamp(20px,4vw,34px);
  border:1px solid var(--cd-line);
  border-left:2px solid var(--cd-line-hard);
  border-radius:var(--cd-r);
  background:var(--cd-panel);
}
.cd-state__tag{
  font-family:var(--cd-mono);
  font-size:10px;
  font-weight:700;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--cd-faint);
}
.cd-state strong{
  font-family:var(--cd-display);
  font-size:17px;
  font-weight:600;
  color:var(--cd-ink);
}
.cd-state p{margin:0;max-width:48ch;color:var(--cd-dim);font-size:13.5px;line-height:1.6}
.cd-state--error{border-left-color:var(--cd-bad)}
.cd-state--error .cd-state__tag{color:var(--cd-bad)}
.cd-state--locked{border-left-color:var(--cd-level)}
.cd-state--locked .cd-state__tag{color:var(--cd-level)}
.cd-state--loading{border-left-color:var(--cd-signal)}
.cd-state--loading .cd-state__tag{color:var(--cd-signal)}

.cd-retry{
  margin-top:3px;
  min-height:38px;
  padding:9px 16px;
  border:1px solid var(--cd-line-hard);
  border-radius:var(--cd-r-chip);
  background:transparent;
  color:var(--cd-ink);
  font-family:var(--cd-display);
  font-size:13px;
  font-weight:600;
  cursor:pointer;
  transition:border-color .2s,background .2s;
}
.cd-retry:hover{border-color:var(--cd-line-hard);background:rgba(247,248,248,.06)}

/* A control that is mid-request says so, and cannot be pressed again. */
[data-busy="true"]{position:relative;pointer-events:none;opacity:.68}
[data-busy="true"]::after{
  content:"";
  position:absolute;
  top:50%;
  right:12px;
  width:11px;
  height:11px;
  margin-top:-6px;
  border:1.5px solid currentColor;
  border-right-color:transparent;
  border-radius:50%;
  animation:cd-spin .7s linear infinite;
}
@keyframes cd-spin{to{transform:rotate(360deg)}}
@media(prefers-reduced-motion:reduce){[data-busy="true"]::after{animation:none;opacity:.5}}

/* Status must never be carried by colour alone. */
.cd-dot{
  display:inline-block;
  width:6px;
  height:6px;
  border-radius:50%;
  background:currentColor;
  vertical-align:middle;
}

/* ═══════════════════════════════════════════════════════════════════════════
   AUTH — part of the Cut Desk, not a separate product.
   A real <dialog>: the browser gives us the top layer, Escape and the
   backdrop; we supply the focus trap and the live region.
   ═══════════════════════════════════════════════════════════════════════════ */

.cd-auth{
  width:min(100%,468px);
  max-height:calc(100dvh - 2rem);
  /* The UA sheet centres a modal dialog with `margin:auto`. Both pages carry a
     `*{margin:0}` reset, which silently wins and pins the dialog to the left —
     so it has to be restored here. */
  margin:auto;
  padding:0;
  border:1px solid var(--cd-line-hard);
  border-radius:var(--cd-r-lg);
  background:var(--cd-panel);
  color:var(--cd-ink);
  overflow:visible;
}
.cd-auth::backdrop{background:rgba(7,6,7,.82)}
.cd-auth[open]{
  display:flex;
  flex-direction:column;
  animation:cd-auth-in .26s var(--cd-snap);
}
@keyframes cd-auth-in{from{opacity:0;transform:translateY(10px)}}
@media(prefers-reduced-motion:reduce){.cd-auth[open]{animation:none}}

.cd-auth__head{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:12px;
  padding:16px 18px 14px;
  border-bottom:1px solid var(--cd-line);
}
.cd-auth__head img{display:block;height:22px;width:auto}
.cd-auth__close{
  display:flex;
  align-items:center;
  justify-content:center;
  width:34px;
  height:34px;
  border:1px solid var(--cd-line);
  border-radius:var(--cd-r-chip);
  background:transparent;
  color:var(--cd-dim);
  font-size:17px;
  line-height:1;
  cursor:pointer;
  transition:color .2s,border-color .2s;
}
.cd-auth__close:hover{color:var(--cd-ink);border-color:var(--cd-line-hard)}

.cd-auth__body{padding:20px 18px 22px;overflow-y:auto}
/* The heading takes focus when the dialog opens so screen readers announce the
   title. That is a programmatic focus, not a keyboard one — it should not draw
   a focus ring at a mouse user.
   ⚠️ A `:focus-visible` companion rule used to sit here and it defeated the
   `outline:none` above: browsers DO match `:focus-visible` on an element that
   is focused programmatically, so opening the dialog in signup mode drew a
   2px cyan rectangle around the title. Sign-in never showed it because that
   mode focuses the email field instead — which is why it only appeared on the
   "open the campaign" route. The heading carries `tabindex="-1"`, so Tab can
   never reach it and the only focus it ever gets is ours; a ring there can
   never inform anyone. Do not add one back. */
.cd-auth h2:focus,
.cd-auth h2:focus-visible{outline:none}
.cd-auth h2{
  margin:0 0 5px;
  font-family:var(--cd-display);
  font-size:23px;
  font-weight:700;
  letter-spacing:-.03em;
}
.cd-auth__sub{margin:0 0 18px;color:var(--cd-dim);font-size:13.5px;line-height:1.55}

/* Role picker — semantic radios. The visual state follows :checked, so
   keyboard, screen readers and pointer all agree. */
.cd-roles{border:0;margin:0 0 16px;padding:0}
.cd-roles legend{
  padding:0 0 8px;
  font-family:var(--cd-mono);
  font-size:10px;
  font-weight:600;
  letter-spacing:.15em;
  text-transform:uppercase;
  color:var(--cd-faint);
}
.cd-roles__grid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.cd-role{position:relative;display:block;cursor:pointer}
.cd-role input{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  margin:0;
  opacity:0;
  cursor:pointer;
}
.cd-role span{
  display:flex;
  flex-direction:column;
  gap:3px;
  min-height:60px;
  padding:11px 12px;
  border:1px solid var(--cd-line);
  border-radius:var(--cd-r);
  background:var(--cd-panel-2);
  transition:border-color .2s,background .2s;
}
.cd-role b{font-family:var(--cd-display);font-size:14px;font-weight:600}
.cd-role small{color:var(--cd-faint);font-size:11.5px;line-height:1.35}
.cd-role input:checked + span{
  border-color:var(--cd-focus);
  background:rgba(121,231,255,.07);
}
.cd-role input:checked + span b{color:var(--cd-ink)}
.cd-role input:focus-visible + span{outline:2px solid var(--cd-focus);outline-offset:2px}

.cd-field{display:flex;flex-direction:column;gap:5px;margin-bottom:11px}
.cd-field label{
  font-family:var(--cd-mono);
  font-size:10px;
  font-weight:600;
  letter-spacing:.13em;
  text-transform:uppercase;
  color:var(--cd-faint);
}
.cd-field input{
  width:100%;
  min-height:46px;
  padding:12px 13px;
  border:1px solid var(--cd-line);
  border-radius:var(--cd-r);
  background:var(--cd-panel-2);
  color:var(--cd-ink);
  font-family:var(--cd-body);
  font-size:15px;   /* 16px-ish keeps iOS from zooming the form on focus */
  outline:none;
  transition:border-color .2s;
}
.cd-field input:focus-visible{border-color:var(--cd-focus);box-shadow:0 0 0 3px rgba(121,231,255,.16)}
.cd-field input::placeholder{color:var(--cd-faint);opacity:.7}

.cd-auth__submit{
  width:100%;
  min-height:48px;
  margin-top:5px;
  border:none;
  border-radius:var(--cd-r);
  background:var(--cd-action);
  color:var(--cd-action-ink);
  font-family:var(--cd-display);
  font-size:15px;
  font-weight:700;
  cursor:pointer;
  transition:filter .2s;
}
.cd-auth__submit:hover{filter:brightness(1.06)}

.cd-auth__status{
  display:none;
  margin-top:11px;
  padding:9px 11px;
  border:1px solid rgba(255,92,92,.4);
  border-left-width:2px;
  border-radius:var(--cd-r-chip);
  background:rgba(255,92,92,.08);
  color:#FFC9C9;
  font-size:13px;
  line-height:1.5;
}
.cd-auth__status.is-shown{display:block}
.cd-auth__status.is-ok{
  border-color:rgba(255,77,157,.4);
  background:rgba(255,77,157,.08);
  color:#FF4D9D;
}

.cd-auth__alt{
  margin-top:13px;
  color:var(--cd-dim);
  font-size:13px;
  text-align:center;
}
.cd-auth__alt button{
  border:none;
  background:none;
  padding:2px 3px;
  color:var(--cd-ink);
  font:inherit;
  font-weight:600;
  cursor:pointer;
  text-decoration:underline;
  text-underline-offset:2px;
}
.cd-auth__or{
  display:flex;
  align-items:center;
  gap:11px;
  margin:17px 0 13px;
  font-family:var(--cd-mono);
  font-size:10px;
  letter-spacing:.15em;
  text-transform:uppercase;
  color:var(--cd-faint);
}
.cd-auth__or::before,.cd-auth__or::after{content:"";flex:1;height:1px;background:var(--cd-line)}

.cd-auth__google{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:9px;
  width:100%;
  min-height:48px;
  border:1px solid var(--cd-line-hard);
  border-radius:var(--cd-r);
  background:var(--cd-panel-2);
  color:var(--cd-ink);
  font-family:var(--cd-body);
  font-size:14px;
  font-weight:600;
  cursor:pointer;
  transition:border-color .2s,background .2s;
}
.cd-auth__google:hover{border-color:var(--cd-line-hard);background:#211A20}
.cd-auth__google svg{width:17px;height:17px;flex:0 0 auto}

.cd-auth__foot{
  margin:16px 0 0;
  padding-top:13px;
  border-top:1px solid var(--cd-line);
  color:var(--cd-faint);
  font-size:11.5px;
  line-height:1.6;
}
.cd-auth__foot a{color:var(--cd-dim)}

@media(max-width:520px){
  /* A bottom sheet on a phone: still horizontally centred, but pinned to the
     bottom edge so it sits above the keyboard rather than behind it. */
  .cd-auth{width:100%;max-width:100%;border-radius:var(--cd-r-lg) var(--cd-r-lg) 0 0;margin:auto auto 0}
  .cd-roles__grid{grid-template-columns:1fr}
  .cd-role span{min-height:52px}
}

/* Platform marks on the outputs stay monochrome: a platform logo is neither a
   verified state nor an action. The silhouette carries the recognition. */
.cde__logo{
  width:12px;
  height:12px;
  flex:0 0 auto;
  color:var(--cd-dim);
  vertical-align:-2px;
  margin-right:6px;
}
.cde__foot small{display:inline-flex;align-items:center}
.cde.is-verified .cde__logo{color:var(--cd-ink)}

/* Data-rich crops — the engine should look like a working edit instrument,
   not a row of empty placeholders. The source frames suggest real scenes and
   captions without introducing stock photography that would fight the site. */
.cde__film i{
  --cde-subject-x:42%;
  --cde-scene:rgba(255,255,255,.13);
  --cde-caption:rgba(255,255,255,.28);
}
.cde__film i:nth-child(3n+2){--cde-subject-x:66%}
.cde__film i:nth-child(4n){--cde-subject-x:30%}
.cde__film i::before{
  content:"";
  position:absolute;
  inset:6px 4px 8px;
  border-radius:2px;
  background:
    linear-gradient(var(--cde-caption),var(--cde-caption)) 50% 78%/72% 3px no-repeat,
    linear-gradient(var(--cde-caption),var(--cde-caption)) 50% 87%/48% 2px no-repeat,
    radial-gradient(circle at var(--cde-subject-x) 31%,var(--cde-scene) 0 10%,transparent 11%),
    radial-gradient(ellipse at var(--cde-subject-x) 66%,var(--cde-scene) 0 20%,transparent 21%),
    linear-gradient(145deg,rgba(255,77,157,.07),transparent 54%);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.035);
}
.cde__film i.is-hot{
  --cde-scene:rgba(255,77,157,.28);
  --cde-caption:rgba(255,255,255,.52);
}

.cde__slot::before{
  content:"9:16";
  position:absolute;
  top:6px;
  left:6px;
  color:var(--cd-faint);
  font-family:var(--cd-mono);
  font-size:7px;
  font-weight:700;
  letter-spacing:.1em;
}
.cde__slot::after{
  content:"";
  position:absolute;
  inset:22px 7px 8px;
  background:
    linear-gradient(90deg,transparent 49%,rgba(255,255,255,.08) 50%,transparent 51%),
    repeating-linear-gradient(180deg,rgba(255,255,255,.055) 0 1px,transparent 1px 18px);
  opacity:.65;
}

.cde__scene{
  position:absolute;
  z-index:1;
  inset:20px 5px 32px;
  overflow:hidden;
  border:1px solid rgba(255,255,255,.08);
  border-radius:2px;
  background:
    linear-gradient(rgba(255,255,255,.035) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,.035) 1px,transparent 1px),
    linear-gradient(155deg,rgba(255,77,157,.12),rgba(9,7,9,.72));
  background-size:14px 14px,14px 14px,auto;
}
.cde__scene small{
  position:absolute;
  z-index:3;
  top:4px;
  left:5px;
  color:rgba(255,255,255,.68);
  font-family:var(--cd-mono);
  font-size:6px;
  font-weight:700;
  letter-spacing:.07em;
  text-transform:uppercase;
}
.cde__subject{
  position:absolute;
  inset:17% 18% 27%;
  background:
    radial-gradient(circle at 50% 28%,rgba(255,255,255,.34) 0 13%,transparent 14%),
    radial-gradient(ellipse at 50% 80%,rgba(255,255,255,.18) 0 29%,transparent 30%);
}
.cde__out:nth-child(1) .cde__subject{transform:translateX(-8%)}
.cde__out:nth-child(3) .cde__subject{transform:translateX(8%)}
.cde__caption{
  position:absolute;
  z-index:2;
  left:9px;
  right:9px;
  bottom:14px;
  height:8px;
  background:
    linear-gradient(rgba(255,255,255,.62),rgba(255,255,255,.62)) 0 0/100% 3px no-repeat,
    linear-gradient(rgba(255,255,255,.35),rgba(255,255,255,.35)) 50% 6px/62% 2px no-repeat;
}
.cde__wave{
  position:absolute;
  left:7px;
  right:7px;
  bottom:4px;
  height:5px;
  background:repeating-linear-gradient(90deg,var(--cd-signal) 0 1px,transparent 1px 5px);
  opacity:.46;
}
.cde--status .cde__scene{bottom:7px}

/* Form labels were 10px. These carry the whole sign-up: the field labels, the
   role legend and the "or" between the two routes in. Nothing about the
   dialog's proportions depends on them being smaller than the input text. */
.cd-roles legend{font-size:12px}
.cd-field label{font-size:12px}
.cd-auth__or{font-size:11px}
