/* ==========================================================================
   Magnet platform — dashboard design system
   ========================================================================== */

@font-face { font-family: 'Morabba'; font-weight: 400; font-display: swap; src: url('/fonts/Morabba-Regular.woff2') format('woff2'); }
@font-face { font-family: 'Morabba'; font-weight: 700; font-display: swap; src: url('/fonts/Morabba-Bold.woff2') format('woff2'); }
@font-face { font-family: 'Morabba'; font-weight: 900; font-display: swap; src: url('/fonts/Morabba-Heavy.woff2') format('woff2'); }
@font-face { font-family: 'YekanBakh'; font-weight: 300; font-display: swap; src: url('/fonts/YekanBakhFaNum-Light.woff2') format('woff2'); }
@font-face { font-family: 'YekanBakh'; font-weight: 400; font-display: swap; src: url('/fonts/YekanBakhFaNum-Regular.woff2') format('woff2'); }
@font-face { font-family: 'YekanBakh'; font-weight: 600; font-display: swap; src: url('/fonts/YekanBakhFaNum-SemiBold.woff2') format('woff2'); }
@font-face { font-family: 'YekanBakh'; font-weight: 700; font-display: swap; src: url('/fonts/YekanBakhFaNum-Bold.woff2') format('woff2'); }

*, *::before, *::after { box-sizing: border-box; }

/* .btn sets display:inline-flex, which outranks the UA [hidden] rule. */
[hidden] { display: none !important; }

:root {
  --mg: #3D1061;
  --mg-2: #5A1B8C;
  --mg-3: #7C3AB0;
  --mg-ink: #1B0A2E;
  --red: #D02244;
  --gray: #878787;
  --bg: #FAF8FC;
  --card: #FFFFFF;
  --line: #E7E1EE;
  --line-2: #F0EBF5;
  --ok: #0F8A6A;
  --warn: #B8860B;

  --r-sm: 10px; --r-md: 14px; --r-lg: 20px;
  --shadow: 0 2px 10px -4px rgba(61,16,97,.14);
  --shadow-lg: 0 24px 60px -28px rgba(61,16,97,.45);
  --ease: cubic-bezier(.22,.61,.36,1);
  --snap: cubic-bezier(.16,1.02,.3,1);

  --f-title: 'Morabba', serif;
  --f-body: 'YekanBakh', system-ui, sans-serif;
}

html, body { margin: 0; padding: 0; height: 100%; }
body {
  background: var(--bg); color: var(--mg-ink);
  font-family: var(--f-body); font-size: 14px; line-height: 1.75;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 { font-family: var(--f-title); font-weight: 700; margin: 0; line-height: 1.3; }
img { max-width: 100%; display: block; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--mg); }
/* Selected text wears the brand red, in the panel as in the deck. */
::selection { background: var(--red); color: #fff; }
::-moz-selection { background: var(--red); color: #fff; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #DCD3E6; border-radius: 8px; border: 2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: #C6B8D6; }

/* ------------------------------------------------------------- primitives */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border: 1px solid var(--line); background: var(--card); color: var(--mg-ink);
  border-radius: var(--r-md); padding: 9px 16px; cursor: pointer;
  font-weight: 500; font-size: 13.5px; white-space: nowrap;
  transition: background .2s, border-color .2s, color .2s, transform .15s var(--ease), opacity .2s;
}
.btn:hover:not(:disabled) { border-color: var(--mg); color: var(--mg); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn svg { width: 16px; height: 16px; flex: none; }

.btn-primary { background: var(--mg); border-color: var(--mg); color: #fff; }
.btn-primary:hover:not(:disabled) { background: var(--mg-2); border-color: var(--mg-2); color: #fff; }
.btn-danger { color: var(--red); }
.btn-danger:hover:not(:disabled) { background: var(--red); border-color: var(--red); color: #fff; }
.btn-ghost { background: transparent; border-color: transparent; }
.btn-ghost:hover:not(:disabled) { background: rgba(61,16,97,.06); }
.btn-sm { padding: 6px 11px; font-size: 12.5px; border-radius: var(--r-sm); }
.btn-icon { padding: 7px; width: 32px; height: 32px; }
.btn-icon.btn-sm { width: 28px; height: 28px; padding: 5px; }
.btn-block { width: 100%; }

/* The export button — the one purple call to action, per the brief. */
.btn-export {
  background: linear-gradient(135deg, var(--mg), var(--mg-3));
  border: 0; color: #fff; font-family: var(--f-title); font-size: 15px;
  padding: 11px 22px; border-radius: var(--r-md);
  box-shadow: 0 8px 22px -10px rgba(61,16,97,.75);
}
.btn-export:hover:not(:disabled) { filter: brightness(1.08); color: #fff; }

.field { display: grid; gap: 6px; margin-bottom: 14px; }
.field > label { font-size: 12.5px; font-weight: 600; color: #5B4A6E; }
.field .hint { font-size: 11.5px; color: var(--gray); line-height: 1.6; }
.input, .select, .textarea {
  width: 100%; background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 10px 13px; outline: none;
  transition: border-color .2s, box-shadow .2s; font-size: 13.5px;
}
.input:focus, .select:focus, .textarea:focus {
  border-color: var(--mg); box-shadow: 0 0 0 3px rgba(61,16,97,.09);
}
.textarea { resize: vertical; min-height: 78px; line-height: 1.9; font-family: var(--f-body); }
.select { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23878787' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: left 12px center; background-size: 16px; padding-left: 34px; }

.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg); }
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  background: rgba(61,16,97,.07); color: var(--mg);
  border-radius: 100px; padding: 3px 10px; font-size: 11.5px; font-weight: 600;
}
.chip-red { background: rgba(208,34,68,.09); color: var(--red); }
.chip-ok { background: rgba(15,138,106,.1); color: var(--ok); }
.chip-gray { background: #F0EDF4; color: var(--gray); }

/* YekanBakh FaNum renders Latin digits as Persian glyphs, which is right for
   copy but wrong for anything the user must type literally (credentials,
   hex colours, keys). Those get a neutral LTR face. */
.tech, code, .input.tech {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  direction: ltr; text-align: left; font-size: .95em;
}

.muted { color: var(--gray); }
.tiny { font-size: 11.5px; }
.center { text-align: center; }
.row { display: flex; align-items: center; gap: 10px; }
.spread { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.grow { flex: 1; min-width: 0; }
.ellip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stack { display: grid; gap: 14px; }

.switch { position: relative; display: inline-block; width: 42px; height: 24px; flex: none; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch i {
  position: absolute; inset: 0; background: #D8CFE2; border-radius: 100px;
  transition: background .25s var(--ease); cursor: pointer;
}
.switch i::before {
  content: ''; position: absolute; width: 18px; height: 18px; top: 3px; right: 3px;
  background: #fff; border-radius: 50%; transition: transform .25s var(--ease);
  box-shadow: 0 1px 3px rgba(0,0,0,.2);
}
.switch input:checked + i { background: var(--mg); }
.switch input:checked + i::before { transform: translateX(-18px); }
.switch input:disabled + i { opacity: .5; cursor: not-allowed; }

/* ==================================================================== LOGIN */

/* Two panels: the brand's own motion on the right, the form on the left.
   The panel reads --mx/--my (−1…1) that the page writes from the pointer;
   every layer drifts with them at its own depth. */
/* ---------------------------------------------------------------- login
   One card on a quiet field. Reading side: the brand stage, purple, with the
   dashed rings turning behind the mark, the claim, three counted figures and
   the colour wheel half off the corner. The other side: the form, on white,
   with a soft light under the pointer. The stage tilts toward the pointer on
   a shallow 3-D plane, the wheel never does. */
.login-page {
  overflow: hidden; min-height: 100%;
  background: #F3EFF7;
  --lp: clamp(12px, 2.2vw, 28px);         /* the card's margin */
}
.login-field { position: fixed; inset: 0; pointer-events: none; overflow: hidden; }
.lf-glow { position: absolute; border-radius: 50%; filter: blur(60px); opacity: .55; }
.lf-glow-a { width: 46vw; height: 46vw; right: -10vw; top: -18vw; background: radial-gradient(circle, rgba(124,58,176,.35), rgba(124,58,176,0) 65%); }
.lf-glow-b { width: 38vw; height: 38vw; left: -8vw; bottom: -16vw; background: radial-gradient(circle, rgba(208,34,68,.22), rgba(208,34,68,0) 65%); }

.login-card {
  position: relative; z-index: 1;
  margin: var(--lp); min-height: calc(100vh - var(--lp) * 2);
  display: grid; grid-template-columns: 1.08fr 1fr;
  border-radius: clamp(18px, 2.4vw, 30px); overflow: hidden;
  background: #fff;
  box-shadow: 0 40px 90px -40px rgba(27,10,46,.45), 0 2px 0 rgba(255,255,255,.6) inset;
  --mx: 0; --my: 0;
}

/* ---- the brand stage */
.login-art {
  position: relative; overflow: hidden; isolation: isolate;
  background: radial-gradient(120% 90% at 85% 10%, #5A1B8C 0%, var(--mg) 45%, #2A0B45 100%);
  color: #fff;
  display: grid;
}
.la-grain {
  position: absolute; inset: 0; z-index: 1; pointer-events: none; opacity: .28; mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .5 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}
.la-wheel {
  position: absolute; z-index: 0; pointer-events: none;
  --w: min(60vh, 42vw); width: var(--w); height: var(--w);
  bottom: calc(var(--w) * -.36); left: calc(var(--w) * -.34);
  filter: saturate(1.05);
}
.la-wheel img { width: 100%; height: 100%; animation: la-spin 34s linear infinite; }
@keyframes la-spin { to { transform: rotate(360deg); } }

.la-scene {
  position: relative; z-index: 2;
  display: flex; flex-direction: column; justify-content: space-between; gap: 24px;
  padding: clamp(28px, 4vw, 56px);
  transform: perspective(900px) rotateY(calc(var(--mx) * 5deg)) rotateX(calc(var(--my) * -3.6deg)) translate3d(calc(var(--mx) * 14px), calc(var(--my) * 10px), 0);
  transition: transform .9s cubic-bezier(.19,.86,.32,1);
  transform-style: preserve-3d;
}
.la-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.la-brand { position: relative; width: clamp(150px, 15vw, 210px); }
.la-mark { display: block; position: relative; z-index: 1; }
.la-mark .mgm { width: 100%; height: auto; color: #fff; display: block; }
/* The rings sit behind the mark, centred on it, and turn at three speeds. */
.la-rings {
  position: absolute; z-index: 0; pointer-events: none; color: #fff;
  width: 280%; aspect-ratio: 1; left: 50%; top: 50%; translate: -50% -50%;
  opacity: .6;
}
.la-rings svg { width: 100%; height: 100%; display: block; overflow: visible; }
.la-ring { transform-origin: 50% 50%; animation: la-spin var(--spin, 40s) linear infinite; }
.la-ring-r { animation-direction: reverse; }
.la-tag {
  font-size: 11.5px; color: rgba(255,255,255,.62); letter-spacing: .02em;
  padding: 6px 11px; border: 1px solid rgba(255,255,255,.18); border-radius: 999px;
  backdrop-filter: blur(6px); white-space: nowrap; margin-top: 4px;
}

.la-mid { translate: calc(var(--mx) * 6px) calc(var(--my) * 4px); transition: translate .9s cubic-bezier(.19,.86,.32,1); }
.login-claim { font-family: var(--f-title); font-size: clamp(28px, 3.6vw, 54px); line-height: 1.32; max-width: 13ch; margin: 0; text-wrap: balance; }
.la-hi { color: #F5B921; font-style: normal; }
.la-w { display: inline-block; }
.la-facts { list-style: none; margin: clamp(22px, 3.4vh, 36px) 0 0; padding: 0; display: flex; gap: clamp(18px, 2.6vw, 40px); flex-wrap: wrap; }
.la-facts li { display: grid; gap: 2px; font-size: 12.5px; color: rgba(255,255,255,.62); position: relative; padding-inline-start: 12px; }
.la-facts li::before { content: ''; position: absolute; inset-inline-start: 0; top: 8px; bottom: 4px; width: 2px; border-radius: 2px; background: linear-gradient(#F5B921, rgba(245,185,33,.15)); }
.la-facts b { font-family: var(--f-title); font-size: clamp(22px, 2.1vw, 32px); color: #fff; line-height: 1.1; font-variant-numeric: tabular-nums; }

.la-foot { display: flex; justify-content: flex-start; align-items: center; gap: 10px; font-size: 11.5px; color: rgba(255,255,255,.5); }
.la-sep { width: 22px; height: 1px; background: rgba(255,255,255,.25); }
.la-now { font-variant-numeric: tabular-nums; }

/* The accent in the claim breathes like the deck's: a swell, a light through
   the letters, a spark on the shoulder that tilts up; one breath every
   second-and-a-bit, tilting one way then the other. */
body.is-in .la-hi {
  display: inline-block; position: relative;
  background: linear-gradient(110deg, #F5B921 0 38%, #fff3cf 46%, #fff 50%, #fff3cf 54%, #F5B921 62% 100%);
  background-size: 260% 100%; background-position: 110% 0;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: ac-breathe-l 4.42s var(--ease) infinite 1.4s;
  transform-origin: 50% 60%;
}
body.is-in .la-hi::before, body.is-in .la-hi::after {
  content: ''; position: absolute; top: -.3em; width: .4em; height: .4em; pointer-events: none;
  background: #F5B921;
  clip-path: polygon(50% 0, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0 50%, 40% 40%);
  opacity: 0; transform: scale(0);
  filter: drop-shadow(0 0 3px rgba(245,185,33,.8));
  animation: ac-spark-l 4.42s var(--ease) infinite 1.4s;
}
body.is-in .la-hi::after { inset-inline-end: -.32em; }
body.is-in .la-hi::before { inset-inline-start: -.32em; animation-name: ac-spark-lb; }
@keyframes ac-breathe-l {
  0%, 22.6% { transform: scale(1) rotate(0deg); background-position: 110% 0; filter: drop-shadow(0 0 0 rgba(245,185,33,0)); }
  31.1%     { transform: scale(1.07) rotate(-5deg); }
  33.4%     { filter: drop-shadow(0 .06em .35em rgba(245,185,33,.45)); }
  38.3%     { background-position: -10% 0; }
  49.99%    { transform: scale(1) rotate(0deg); background-position: -10% 0; filter: drop-shadow(0 0 0 rgba(245,185,33,0)); }
  50%, 72.6% { transform: scale(1) rotate(0deg); background-position: 110% 0; filter: drop-shadow(0 0 0 rgba(245,185,33,0)); }
  81.1%     { transform: scale(1.07) rotate(5deg); }
  83.4%     { filter: drop-shadow(0 .06em .35em rgba(245,185,33,.45)); }
  88.3%     { background-position: -10% 0; }
  100%      { transform: scale(1) rotate(0deg); background-position: -10% 0; filter: drop-shadow(0 0 0 rgba(245,185,33,0)); }
}
@keyframes ac-spark-l {
  0%, 29.3%  { opacity: 0; transform: scale(0) rotate(0deg); }
  33.8%      { opacity: 1; transform: scale(1) rotate(35deg); }
  41%, 100%  { opacity: 0; transform: scale(.2) rotate(90deg) translate(.2em, -.2em); }
}
@keyframes ac-spark-lb {
  0%, 79.3%  { opacity: 0; transform: scale(0) rotate(0deg); }
  83.8%      { opacity: 1; transform: scale(1) rotate(-35deg); }
  91%, 100%  { opacity: 0; transform: scale(.2) rotate(-90deg) translate(-.2em, -.2em); }
}

/* ---- the form pane */
.login-form {
  position: relative; display: grid; place-items: center;
  padding: clamp(28px, 4vw, 56px); background: #fff; overflow: hidden;
  --sx: 50%; --sy: 50%;
}
.lf-spot {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(420px circle at var(--sx) var(--sy), rgba(124,58,176,.09), transparent 62%);
  transition: opacity .4s; opacity: 0;
}
.login-form:hover .lf-spot { opacity: 1; }
.login-box { width: min(380px, 100%); position: relative; }
.lb-eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 11.5px; color: var(--mg-3); letter-spacing: .04em; margin-bottom: 14px;
}
.lb-eyebrow::before { content: ''; width: 22px; height: 2px; border-radius: 2px; background: var(--red); }
.login-box h1 { font-size: clamp(28px, 2.6vw, 36px); color: var(--mg-ink); margin: 0 0 6px; letter-spacing: -.01em; }
.login-box > p { color: var(--gray); margin: 0 0 30px; font-size: 13.5px; }
.login-err {
  background: rgba(208,34,68,.07); color: var(--red); border-radius: var(--r-md);
  padding: 0 14px; font-size: 12.5px; margin-bottom: 0; max-height: 0; opacity: 0; overflow: hidden;
  border-inline-start: 3px solid transparent;
  transition: max-height .35s var(--ease), opacity .3s, padding .35s var(--ease), margin .35s var(--ease), border-color .3s;
}
.login-err.show { max-height: 80px; opacity: 1; padding: 10px 14px; margin-bottom: 16px; border-color: var(--red); }

/* Fields: the label floats inside the box and rises on focus or content; a
   hairline draws under the field on focus; an eye that only appears once
   there is something to show. */
.lf { margin-bottom: 14px; }
.lf-box { position: relative; }
.lf .input {
  height: 56px; padding: 22px 16px 6px; font-size: 15px;
  background: #FAF8FC; border: 1px solid var(--line); border-radius: 14px;
  transition: border-color .25s, box-shadow .25s, background .25s, transform .25s var(--ease);
}
.lf .input:hover { border-color: #D9CFE6; }
.lf .input:focus { background: #fff; border-color: var(--mg); box-shadow: 0 0 0 4px rgba(61,16,97,.08); transform: none; }
.lf-box > label {
  position: absolute; inset-inline-start: 16px; top: 50%; translate: 0 -50%;
  font-size: 14px; color: var(--gray); pointer-events: none; font-weight: 500;
  transition: top .25s var(--snap), font-size .25s var(--snap), color .2s, translate .25s var(--snap);
  transform-origin: 100% 50%;
}
.lf .input:focus ~ label, .lf.has-value .lf-box > label, .lf .input:not(:placeholder-shown) ~ label {
  top: 11px; translate: 0 0; font-size: 11px; color: var(--mg-3);
}
.lf-line {
  position: absolute; bottom: 0; inset-inline: 14px; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, var(--red), var(--mg-3)); transform: scaleX(0); transform-origin: 100% 50%;
  transition: transform .45s var(--snap); pointer-events: none;
}
.lf .input:focus ~ .lf-line { transform: scaleX(1); }
.lf-eye {
  position: absolute; top: 50%; left: 10px; translate: 0 -50%;   /* physical: the field's text runs LTR */
  width: 34px; height: 34px; border: 0; border-radius: 10px; background: transparent;
  display: grid; place-items: center; color: var(--gray); cursor: pointer;
  opacity: 0; transition: opacity .2s, color .2s, background .2s;
}
.lf-eye svg { width: 17px; height: 17px; }
.lf.has-value .lf-eye, .lf:focus-within .lf-eye { opacity: 1; }
.lf-eye:hover { color: var(--mg); background: rgba(61,16,97,.06); }
.lf .input#p { padding-left: 50px; }
.lf-caps { color: var(--warn); display: block; margin-top: 6px; }

/* The button: a pill that is magnetic under the pointer (--bx/--by from the
   page), carries a light that sweeps on hover, gives way to a spinner dead
   centre while the request is out, and ticks when it lands. */
.login-go {
  --bx: 0px; --by: 0px;
  position: relative; width: 100%; height: 56px; margin-top: 10px; border: 0; cursor: pointer;
  border-radius: 999px; color: #fff; font: inherit; font-weight: 700; font-size: 15px;
  background: linear-gradient(100deg, var(--mg-2), var(--mg) 55%, #2A0B45);
  box-shadow: 0 14px 30px -14px rgba(61,16,97,.7), 0 1px 0 rgba(255,255,255,.18) inset;
  overflow: hidden; isolation: isolate;
  translate: var(--bx) var(--by);
  transition: translate .35s cubic-bezier(.19,.86,.32,1), box-shadow .3s, filter .3s;
}
.login-go::before {
  content: ''; position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(105deg, transparent 30%, rgba(255,255,255,.22) 50%, transparent 70%);
  translate: 120% 0; transition: translate .8s cubic-bezier(.19,.86,.32,1);
}
.login-go:hover:not(:disabled) { box-shadow: 0 20px 40px -16px rgba(61,16,97,.75), 0 1px 0 rgba(255,255,255,.22) inset; filter: brightness(1.06); }
.login-go:hover:not(:disabled)::before { translate: -120% 0; }
.login-go:active:not(:disabled) { translate: calc(var(--bx) * .5) calc(var(--by) * .5 + 1px); }
.login-go:disabled { cursor: progress; }
.lg-in {
  position: relative; z-index: 1; display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  translate: calc(var(--bx) * .35) calc(var(--by) * .35);
  transition: translate .35s cubic-bezier(.19,.86,.32,1), opacity .25s, transform .3s var(--snap);
}
.lg-arrow { width: 18px; height: 18px; display: inline-grid; place-items: center; transition: transform .35s var(--snap); }
.lg-arrow svg { width: 18px; height: 18px; }
.login-go:hover:not(:disabled) .lg-arrow { transform: translateX(-4px); }
.lg-spin {
  position: absolute; inset: 0; margin: auto; z-index: 1; width: 22px; height: 22px; border-radius: 50%;
  border: 2.5px solid rgba(255,255,255,.28); border-top-color: #fff;
  opacity: 0; transform: scale(.4); transition: opacity .25s, transform .3s var(--snap);
}
.login-go.is-busy .lg-in { opacity: 0; transform: scale(.9); }
.login-go.is-busy .lg-spin { opacity: 1; transform: scale(1); animation: spin .7s linear infinite; }
/* Landed: the spinner closes into a tick. */
.login-go.is-done .lg-in { opacity: 0; }
.login-go.is-done .lg-spin {
  opacity: 1; transform: none; animation: none; border-color: #fff; border-radius: 0; border-width: 0 0 2.5px 2.5px;
  width: 18px; height: 9px; rotate: -45deg; translate: 0 -3px; transition: all .3s var(--snap);
}
.login-box.is-shake { animation: lf-shake .42s var(--ease); }
@keyframes lf-shake { 20% { transform: translateX(-7px); } 45% { transform: translateX(6px); } 70% { transform: translateX(-3px); } }

/* ---- entrance: the card rises from a soft blur; the panel wipes in from
   its outer edge; its layers follow; then the form's rows, one after another.
   All of it from one class on <body>; nothing waits on script after that. */
.login-card { opacity: 0; transform: translateY(18px) scale(.985); filter: blur(6px); transition: opacity .7s var(--ease), transform .9s cubic-bezier(.19,.86,.32,1), filter .7s var(--ease); }
body.is-in .login-card { opacity: 1; transform: none; filter: none; }
.login-art { clip-path: inset(0 0 0 100% round 0); transition: clip-path .8s cubic-bezier(.62,.02,.2,1) .15s; }
body.is-in .login-art { clip-path: inset(0); }
.la-head, .la-mid, .la-foot, .la-wheel { opacity: 0; transform: translateY(14px); transition: opacity .7s var(--ease), transform .8s cubic-bezier(.19,.86,.32,1), translate .9s cubic-bezier(.19,.86,.32,1); }
.la-wheel { transform: translate3d(-30px, 30px, 0) rotate(-12deg); }
body.is-in .la-head, body.is-in .la-mid, body.is-in .la-foot, body.is-in .la-wheel { opacity: 1; transform: none; }
body.is-in .la-head { transition-delay: .45s; }
body.is-in .la-mid { transition-delay: .55s; }
body.is-in .la-foot { transition-delay: .7s; }
body.is-in .la-wheel { transition-delay: .5s; transition-duration: 1.1s; }
.la-w { opacity: 0; transform: translateY(12px); transition: opacity .6s var(--ease), transform .7s cubic-bezier(.19,.86,.32,1); }
body.is-in .la-w { opacity: 1; transform: none; }
body.is-in .la-w:nth-child(1) { transition-delay: .6s; }
body.is-in .la-w:nth-child(2) { transition-delay: .66s; }
body.is-in .la-w:nth-child(3) { transition-delay: .72s; }
body.is-in .la-w:nth-child(4) { transition-delay: .78s; }
body.is-in .la-w:nth-child(5) { transition-delay: .84s; }
.login-box > * { opacity: 0; transform: translateY(12px); transition: opacity .55s var(--ease), transform .65s cubic-bezier(.19,.86,.32,1); }
body.is-in .login-box > * { opacity: 1; transform: none; }
body.is-in .login-box > :nth-child(1) { transition-delay: .35s; }
body.is-in .login-box > :nth-child(2) { transition-delay: .41s; }
body.is-in .login-box > :nth-child(3) { transition-delay: .47s; }
body.is-in .login-box > :nth-child(4) { transition-delay: .53s; }
body.is-in .login-box > :nth-child(5) { transition-delay: .59s; }
body.is-in .login-box > :nth-child(6) { transition-delay: .65s; }
body.is-in .login-box > :nth-child(7) { transition-delay: .71s; }
body.is-in .login-box > :nth-child(8) { transition-delay: .77s; }
/* The error row is a transition of its own size, not of the entrance. */
body.is-in .login-box > .login-err { transform: none; transition: max-height .35s var(--ease), opacity .3s, padding .35s var(--ease), margin .35s var(--ease), border-color .3s; }
/* The button's own translate must win over the entrance rule. */
body.is-in .login-box > .login-go { transition: translate .35s cubic-bezier(.19,.86,.32,1), box-shadow .3s, filter .3s, opacity .55s var(--ease), transform .65s cubic-bezier(.19,.86,.32,1); }
/* Signed in: the purple stage sweeps over the form while the app loads. */
body.is-out .login-art { clip-path: inset(0 -100% 0 0); transition: clip-path .6s cubic-bezier(.62,.02,.2,1); z-index: 5; }
body.is-out .login-box { opacity: .25; transition: opacity .4s; }

/* Quiet maker's credit, never competing with the form. */
.by {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  margin-top: 34px; padding-top: 22px; border-top: 1px solid var(--line-2);
  text-decoration: none; opacity: .55; transition: opacity .25s var(--ease);
}
.by:hover { opacity: .9; }
.by .by-mark { display: block; color: var(--mg-ink); }
.by-mark svg { height: 24px; width: auto; display: block; }

@media (max-width: 900px) {
  .login-page { overflow: auto; --lp: 10px; }
  .login-card { grid-template-columns: 1fr; min-height: 0; }
  .login-art { min-height: 300px; }
  .la-scene { padding: 24px; transform: none; }
  .login-claim { font-size: 24px; }
  .la-facts { display: none; }
  .la-wheel { --w: 60vw; }
  .la-brand { width: 120px; }
  .login-form { padding: 28px 22px 34px; }
}
@media (prefers-reduced-motion: reduce) {
  .login-card, .login-art, .la-head, .la-mid, .la-foot, .la-wheel, .la-w, .login-box > * { transition: none !important; opacity: 1 !important; transform: none !important; clip-path: none !important; filter: none !important; }
  .la-ring, .la-wheel img, .la-hi, .la-hi::before, .la-hi::after { animation: none !important; }
  .la-scene { transform: none !important; }
  .login-box.is-shake { animation: none; }
}

/* The Lottie cut of the mark, when the player and animation are present,
   sits exactly where the SVG was and hides it. */
.side-logo, .la-mark { position: relative; }
.has-motion > .mgm { visibility: hidden; }
.logo-motion { position: absolute; inset: 0; display: block; }
.logo-motion svg { width: 100% !important; height: 100% !important; display: block; }
.side-logo { cursor: pointer; }

/* ==================================================================== SHELL */

.app { display: grid; grid-template-columns: 232px 1fr; min-height: 100vh; }

.side {
  background: var(--mg); color: #fff; display: flex; flex-direction: column;
  padding: 22px 16px; position: sticky; top: 0; height: 100vh; gap: 6px;
}
.side-logo { color: #fff; width: 120px; margin: 0 6px 26px; }
.side-logo .mgm { width: 100%; height: auto; }
.side-nav { display: grid; gap: 2px; }
.side-nav button {
  display: flex; align-items: center; gap: 11px; width: 100%;
  background: transparent; border: 0; color: rgba(255,255,255,.72);
  padding: 10px 12px; border-radius: var(--r-md); cursor: pointer;
  font-size: 13.5px; text-align: start;
  transition: background .2s, color .2s;
}
.side-nav button:hover { background: rgba(255,255,255,.09); color: #fff; }
.side-nav button.is-on { background: #fff; color: var(--mg); font-weight: 600; }
.side-nav svg { width: 17px; height: 17px; flex: none; }
.side-sep { height: 1px; background: rgba(255,255,255,.13); margin: 14px 6px; }
.side-foot { margin-top: auto; display: grid; gap: 10px; }
.side-user { display: flex; align-items: center; gap: 10px; padding: 8px 6px; }
.side-av {
  width: 36px; height: 36px; border-radius: 50%; overflow: hidden; flex: none;
  background: rgba(255,255,255,.16); cursor: pointer; padding: 0; border: 0;
  transition: transform .35s var(--snap), box-shadow .3s;
}
.side-av img { width: 100%; height: 100%; object-fit: cover; display: block; }
.side-av:hover { transform: scale(1.08); box-shadow: 0 0 0 3px rgba(255,255,255,.22); }

.av-sm { width: 30px; height: 30px; border-radius: 50%; overflow: hidden; flex: none; background: var(--bg); }
.av-sm img { width: 100%; height: 100%; object-fit: cover; display: block; }
.av-now { width: 54px; height: 54px; border-radius: 16px; overflow: hidden; flex: none; background: var(--bg); }
.av-now img { width: 100%; height: 100%; object-fit: cover; display: block; }

.av-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(74px, 1fr));
  gap: 10px; max-height: 46vh; overflow-y: auto; padding-inline-end: 4px;
}
.av-i {
  border: 2px solid transparent; border-radius: 16px; overflow: hidden; padding: 0;
  background: none; cursor: pointer; aspect-ratio: 1;
  transition: transform .3s var(--snap), border-color .2s;
}
.av-i img { width: 100%; height: 100%; display: block; }
.av-i:hover { transform: translateY(-3px) scale(1.04); border-color: var(--mg-3); }
.av-i.is-on { border-color: var(--mg); }

/* Square crop */
.crop-wrap { position: relative; width: 320px; max-width: 100%; margin-inline: auto; }
.crop-cv { width: 100%; aspect-ratio: 1; border-radius: 18px; display: block; cursor: grab; touch-action: none; }
.crop-cv:active { cursor: grabbing; }
.crop-ring {
  position: absolute; inset: 0; border-radius: 18px; pointer-events: none;
  box-shadow: inset 0 0 0 2px var(--mg), inset 0 0 0 999px rgba(0,0,0,0);
}
.crop-range { width: 100%; accent-color: var(--mg); }
.side-user b { display: block; font-family: var(--f-body); font-weight: 600; font-size: 13px; }
.side-user span { font-size: 11px; color: rgba(255,255,255,.55); }

.main { min-width: 0; display: flex; flex-direction: column; }
.topbar {
  display: flex; align-items: center; gap: 14px;
  padding: 16px clamp(16px, 3vw, 34px);
  border-bottom: 1px solid var(--line); background: rgba(250,248,252,.86);
  backdrop-filter: blur(12px); position: sticky; top: 0; z-index: 30;
}
.topbar h2 { font-size: 21px; color: var(--mg); }
.topbar .sub { color: var(--gray); font-size: 12.5px; }
.page { padding: clamp(18px, 3vw, 32px); flex: 1; }

.burger { display: none; }

/* Always fixed: as a normal grid child it would claim a cell and push
   .main onto a second row. */
.scrim {
  position: fixed; inset: 0; background: rgba(27,10,46,.45); z-index: 55;
  opacity: 0; visibility: hidden; transition: opacity .3s, visibility .3s;
}
.scrim.is-open { opacity: 1; visibility: visible; }

@media (max-width: 900px) {
  .app { grid-template-columns: 1fr; }
  .side {
    position: fixed; inset: 0 auto 0 auto; right: 0; width: 250px; z-index: 60; height: 100dvh;
    transform: translateX(100%); transition: transform .3s var(--ease);
  }
  .side.is-open { transform: none; box-shadow: var(--shadow-lg); }
  .burger { display: inline-flex; }
}

/* ============================================================== PROPOSALS  */

.toolbar-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 20px; }
.search { position: relative; flex: 1; min-width: 190px; max-width: 340px; }
.search .input { padding-right: 36px; }
.search svg { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; color: var(--gray); pointer-events: none; }

/* Proposal cards read as rows of information — address, counts, owner — so
   they earn more horizontal room than a square tile. */
.p-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(400px, 1fr)); gap: 16px; }
@media (max-width: 900px) { .p-grid { grid-template-columns: 1fr; } }
.p-card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 18px; display: grid; gap: 13px; align-content: start;
  transition: border-color .22s, transform .22s var(--ease), box-shadow .22s;
  position: relative; overflow: hidden;
}
.p-card:hover { border-color: var(--mg); transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.p-card-top { display: flex; align-items: flex-start; gap: 12px; }
.p-swatch {
  width: 42px; height: 42px; border-radius: 12px; flex: none;
  display: grid; place-items: center; overflow: hidden;
  border: 1px solid var(--line-2); background: #fff;
}
.p-swatch img { width: 100%; height: 100%; object-fit: contain; padding: 4px; }
.p-card h3 { font-size: 16px; color: var(--mg); line-height: 1.5; }
.p-card .p-client { font-size: 12px; color: var(--gray); }
.p-meta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.p-actions { display: flex; gap: 6px; padding-top: 12px; border-top: 1px solid var(--line-2); }

.empty { text-align: center; padding: 70px 20px; color: var(--gray); }
.empty svg { width: 54px; height: 54px; color: var(--line); margin: 0 auto 16px; }
.empty h3 { color: var(--mg-ink); font-size: 18px; margin-bottom: 7px; }

/* Every card names its author, since the whole team shares the list. */
.p-owner { display: flex; align-items: center; gap: 6px; min-width: 0; }
.p-owner-av { width: 18px; height: 18px; border-radius: 50%; flex: none; object-fit: cover; }

/* ================================================================= EDITOR  */

.editor { display: grid; grid-template-columns: 272px 348px 1fr; gap: 0; height: calc(100vh - 65px); }
.ed-col { display: grid; grid-template-rows: auto 1fr; min-width: 0; min-height: 0; border-left: 1px solid var(--line); background: var(--card); }
.ed-col > header {
  display: flex; align-items: center; gap: 8px; padding: 11px 14px;
  border-bottom: 1px solid var(--line); background: var(--card);
}
.ed-col > header b { font-size: 13px; color: var(--mg); }
.ed-scroll { overflow-y: auto; min-height: 0; padding: 12px; }
.ed-list {
  border-left: 1px solid var(--line); overflow-y: auto;
  padding: 14px; background: var(--card); display: grid; gap: 6px; align-content: start;
}
.ed-modhead {
  display: flex; align-items: center; gap: 8px; padding: 9px 10px;
  background: var(--bg); border-radius: var(--r-sm); margin-top: 8px;
  font-size: 12px; font-weight: 600; color: var(--mg); position: sticky; top: 0; z-index: 2;
}
.ed-modhead:first-child { margin-top: 0; }
.ed-modhead .grow { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.ed-slide {
  display: flex; align-items: center; gap: 9px; padding: 9px 10px;
  border: 1px solid transparent; border-radius: var(--r-sm); cursor: pointer;
  transition: background .18s, border-color .18s;
  background: transparent;
}
.ed-slide:hover { background: var(--bg); }
.ed-slide.is-on { background: rgba(61,16,97,.07); border-color: var(--mg); }
.ed-slide.is-off { opacity: .42; }
.ed-slide.is-drag { opacity: .35; }
.ed-slide.drop-before { box-shadow: 0 -2px 0 var(--red); }
.ed-slide.drop-after { box-shadow: 0 2px 0 var(--red); }
.ed-n { font-family: var(--f-title); font-size: 11.5px; color: var(--gray); min-width: 20px; }
.ed-slide b { font-size: 12.5px; font-weight: 500; display: block; }
.ed-slide small { font-size: 10.5px; color: var(--gray); display: block; }
.ed-grip { color: #C9BDD8; cursor: grab; width: 14px; height: 14px; flex: none; }
.ed-grip:active { cursor: grabbing; }

.ed-main { display: grid; grid-template-rows: auto 1fr; min-width: 0; overflow: hidden; }
.ed-tabs { display: flex; gap: 4px; padding: 12px 16px 0; border-bottom: 1px solid var(--line); background: var(--card); }
.ed-tab {
  background: transparent; border: 0; border-bottom: 2px solid transparent;
  padding: 8px 14px; cursor: pointer; color: var(--gray); font-size: 13px;
  transition: color .2s, border-color .2s;
}
.ed-tab.is-on { color: var(--mg); border-color: var(--mg); font-weight: 600; }
.ed-body { overflow: hidden; min-height: 0; display: grid; }

.ed-pane { overflow-y: auto; padding: 20px clamp(16px, 2.4vw, 28px); }
.ed-pane[hidden] { display: none; }

.ed-preview { position: relative; background: #EFEAF4; display: grid; }
.seg { display: flex; background: var(--bg); border-radius: var(--r-sm); padding: 3px; gap: 2px; }
.seg button {
  border: 0; background: transparent; padding: 5px 11px; border-radius: 7px;
  cursor: pointer; font-size: 12px; color: var(--gray); transition: background .2s, color .2s;
}
.seg button.is-on { background: var(--card); color: var(--mg); font-weight: 600; box-shadow: var(--shadow); }

/* Field editor */
.fld-group { border: 1px solid var(--line); border-radius: var(--r-md); padding: 13px; margin-bottom: 12px; background: var(--card); }
.fld-group > header { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; }
.fld-group > header b { font-size: 12.5px; color: var(--mg); }
.rep-item { border: 1px solid var(--line-2); border-radius: var(--r-sm); padding: 11px; margin-bottom: 9px; background: var(--bg); }
.rep-head { display: flex; align-items: center; gap: 8px; margin-bottom: 9px; }
.rep-head b { font-size: 11.5px; color: var(--gray); flex: 1; }

.img-field { display: flex; gap: 10px; align-items: center; }
.img-prev {
  width: 62px; height: 62px; border-radius: var(--r-sm); border: 1px dashed var(--line);
  display: grid; place-items: center; overflow: hidden; flex: none; background: var(--bg);
}
.img-prev img { width: 100%; height: 100%; object-fit: contain; }
.img-prev svg { width: 20px; height: 20px; color: var(--line); }

/* ================================================================== MODAL  */

.modal-bg {
  position: fixed; inset: 0; background: rgba(27,10,46,.5); backdrop-filter: blur(4px);
  display: grid; place-items: center; padding: 20px; z-index: 100;
  opacity: 0; visibility: hidden; transition: opacity .25s, visibility .25s;
}
.modal-bg.is-open { opacity: 1; visibility: visible; }
.modal {
  background: var(--card); border-radius: var(--r-lg); width: min(560px, 100%);
  max-height: 90vh; overflow-y: auto; box-shadow: var(--shadow-lg);
  transform: translateY(14px) scale(.985); transition: transform .28s var(--ease);
}
.modal-bg.is-open .modal { transform: none; }
.modal-wide { width: min(900px, 100%); }
.modal-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 18px 22px; border-bottom: 1px solid var(--line); position: sticky; top: 0; background: var(--card); z-index: 2; border-radius: var(--r-lg) var(--r-lg) 0 0; }
.modal-head h3 { font-size: 18px; color: var(--mg); }
.modal-body { padding: 22px; }
.modal-foot { display: flex; gap: 9px; justify-content: flex-start; padding: 16px 22px; border-top: 1px solid var(--line); position: sticky; bottom: 0; background: var(--card); }

/* Wizard */
.wiz-steps { display: flex; gap: 6px; margin-bottom: 22px; }
.wiz-step { flex: 1; display: grid; gap: 6px; }
.wiz-step i { height: 3px; background: var(--line); border-radius: 3px; transition: background .3s; }
.wiz-step.is-on i, .wiz-step.is-done i { background: var(--mg); }
.wiz-step span { font-size: 11px; color: var(--gray); }
.wiz-step.is-on span { color: var(--mg); font-weight: 600; }

.tpl-list { display: grid; gap: 10px; }
.tpl {
  border: 1px solid var(--line); border-radius: var(--r-md); padding: 14px;
  cursor: pointer; display: grid; gap: 5px; text-align: start; background: var(--card);
  transition: border-color .2s, background .2s;
}
.tpl:hover { border-color: var(--mg-3); }
.tpl.is-on { border-color: var(--mg); background: rgba(61,16,97,.04); }
.tpl b { color: var(--mg); font-size: 14px; }
.tpl p { margin: 0; font-size: 12px; color: var(--gray); line-height: 1.8; }

.mod-list { display: grid; gap: 8px; max-height: 340px; overflow-y: auto; padding-inline-end: 4px; }
.mod-row {
  display: flex; align-items: center; gap: 12px; padding: 11px 13px;
  border: 1px solid var(--line); border-radius: var(--r-md); background: var(--card);
}
.mod-row.is-off { opacity: .55; }
.mod-row b { font-size: 13px; display: block; }
.mod-row small { font-size: 11px; color: var(--gray); display: block; line-height: 1.6; }

/* Slide picker */
.pick-cats { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 16px; }
.pick-cat { border: 1px solid var(--line); background: var(--card); border-radius: 100px; padding: 5px 14px; cursor: pointer; font-size: 12.5px; color: var(--gray); transition: all .2s; }
.pick-cat.is-on { background: var(--mg); border-color: var(--mg); color: #fff; }

/* Bundled artwork picker */
.stock-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px; max-height: 52vh; overflow-y: auto; padding-inline-end: 4px;
}
.stock-i {
  border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden;
  background: var(--card); cursor: pointer; padding: 0; display: grid; gap: 0;
  transition: border-color .2s, transform .2s var(--ease);
}
.stock-i:hover { border-color: var(--mg); transform: translateY(-2px); }
.stock-i img { width: 100%; aspect-ratio: 16/10; object-fit: cover; display: block; }
.stock-i span {
  font-size: 11.5px; color: var(--mg-ink); padding: 7px 9px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Colour picker */
.color-row { display: flex; gap: 8px; align-items: center; }
.color-swatches { display: flex; gap: 6px; flex-wrap: wrap; }
.color-sw { width: 26px; height: 26px; border-radius: 8px; border: 2px solid transparent; cursor: pointer; padding: 0; }
.color-sw.is-on { border-color: var(--mg-ink); }
input[type=color] { width: 44px; height: 38px; padding: 2px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--card); cursor: pointer; }

/* ================================================================== TOAST  */

#toasts { position: fixed; bottom: 20px; left: 20px; z-index: 200; display: grid; gap: 9px; }
.toast {
  background: var(--mg-ink); color: #fff; border-radius: var(--r-md);
  padding: 12px 18px; font-size: 13px; box-shadow: var(--shadow-lg);
  display: flex; align-items: center; gap: 10px; max-width: 380px;
  animation: toast-in .32s var(--ease);
}
.toast.is-err { background: var(--red); }
.toast.is-ok { background: var(--ok); }
.toast svg { width: 17px; height: 17px; flex: none; }
@keyframes toast-in { from { opacity: 0; transform: translateY(14px); } }

/* ========================================================= MICRO-DETAIL  */

/* The export button is the one destination in the app — it earns a slow
   sheen that runs on hover only, so it never nags in peripheral vision. */
.btn-export { position: relative; overflow: hidden; }
.btn-export::after {
  content: ''; position: absolute; top: 0; bottom: 0; width: 40%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.3), transparent);
  transform: translateX(-180%); pointer-events: none;
}
.btn-export:hover:not(:disabled)::after { animation: btn-sheen .85s var(--ease); }
@keyframes btn-sheen { to { transform: translateX(320%); } }

/* Sidebar: the active item's marker slides rather than blinking. */
.side-nav button { position: relative; }
.side-nav button::before {
  content: ''; position: absolute; inset-inline-start: 0; top: 50%;
  width: 3px; height: 0; background: #fff; border-radius: 3px;
  transform: translateY(-50%);
  transition: height .32s var(--snap);
}
.side-nav button:hover::before { height: 40%; }
.side-nav button.is-on::before { height: 0; }
.side-nav svg { transition: transform .4s var(--snap); }
.side-nav button:hover svg { transform: scale(1.14); }

@media (hover: hover) and (pointer: fine) {
  /* Proposal and library cards lean toward the cursor — the same magnetic
     idea as the deck, at a smaller amplitude because these are dense grids. */
  .p-card { transition: transform .45s var(--snap), border-color .22s, box-shadow .22s; }
  .p-card:hover { transform: translateY(-3px); }
  .p-card .p-swatch { transition: transform .45s var(--snap); }
  .p-card:hover .p-swatch { transform: scale(1.09) rotate(-4deg); }

  /* Template and slide-type tiles nudge in the reading direction. */
  .tpl { transition: border-color .2s, background .2s, transform .35s var(--snap); }
  .tpl:hover { transform: translateX(-3px); }

  /* Slide rows in the editor reveal their grip as you approach. */
  .ed-grip { opacity: .45; transition: opacity .2s, transform .3s var(--snap); }
  .ed-slide:hover .ed-grip { opacity: 1; transform: scale(1.15); }

  /* Icon buttons pop very slightly — enough to confirm the target. */
  .btn-icon { transition: background .2s, border-color .2s, color .2s, transform .3s var(--snap); }
  .btn-icon:hover:not(:disabled) { transform: scale(1.09); }
}

/* Toasts arrive with a slight overshoot instead of a linear slide. */
.toast { animation: toast-in .4s var(--snap); }

@media (prefers-reduced-motion: reduce) {
  .btn-export::after, .toast { animation: none !important; }
  .p-card, .tpl, .pk-card, .btn-icon, .side-nav svg { transition: none !important; transform: none !important; }
  .pk-frame, .pk-skel { transition: none !important; animation: none !important; }
}

/* ================================================== DASHBOARD MOTION  */

/* Every page arrives the same way: a short rise and fade, once. Lists inside
   it stagger by position — twelve rungs of 35ms, then everything together —
   so a long list is never a wait. The rules are all `animation`, which
   leaves hover transitions untouched. */
.page.is-enter { animation: page-in .38s var(--ease) backwards; }
@keyframes page-in { from { opacity: 0; transform: translateY(8px); } }
.tb-title h2, .tb-title .sub { animation: page-in .45s var(--ease) backwards; }
.tb-title .sub { animation-delay: .06s; }
.tb-today {
  font-size: 12px; color: var(--gray); white-space: nowrap;
  padding: 5px 12px; border-radius: 100px; background: var(--card); border: 1px solid var(--line);
  animation: page-in .5s var(--ease) backwards; animation-delay: .1s;
}
@media (max-width: 600px) { .tb-today { display: none; } }

.p-card, .mod-row, .tpl, .tbl-a tbody tr, .stat-tile, .fld-group, .pk-card {
  animation: row-in .45s var(--ease) backwards;
  animation-delay: calc(min(var(--k, 0), 12) * 35ms);
}
@keyframes row-in { from { opacity: 0; transform: translateY(8px); } }
/* Lists that carry no --k get one from their position. */
.p-grid > :nth-child(1), .mod-list > :nth-child(1), .tpl-list > :nth-child(1), .tbl-a tbody tr:nth-child(1) { --k: 0; }
.p-grid > :nth-child(2), .mod-list > :nth-child(2), .tpl-list > :nth-child(2), .tbl-a tbody tr:nth-child(2) { --k: 1; }
.p-grid > :nth-child(3), .mod-list > :nth-child(3), .tpl-list > :nth-child(3), .tbl-a tbody tr:nth-child(3) { --k: 2; }
.p-grid > :nth-child(4), .mod-list > :nth-child(4), .tpl-list > :nth-child(4), .tbl-a tbody tr:nth-child(4) { --k: 3; }
.p-grid > :nth-child(5), .mod-list > :nth-child(5), .tpl-list > :nth-child(5), .tbl-a tbody tr:nth-child(5) { --k: 4; }
.p-grid > :nth-child(6), .mod-list > :nth-child(6), .tpl-list > :nth-child(6), .tbl-a tbody tr:nth-child(6) { --k: 5; }
.p-grid > :nth-child(7), .mod-list > :nth-child(7), .tpl-list > :nth-child(7), .tbl-a tbody tr:nth-child(7) { --k: 6; }
.p-grid > :nth-child(8), .mod-list > :nth-child(8), .tpl-list > :nth-child(8), .tbl-a tbody tr:nth-child(8) { --k: 7; }
.p-grid > :nth-child(n+9), .mod-list > :nth-child(n+9), .tpl-list > :nth-child(n+9), .tbl-a tbody tr:nth-child(n+9) { --k: 8; }
/* A card that is being dragged or re-rendered mid-edit must not replay. */
.ed-list .slide-row, .ed-slide { animation: none; }

/* The proposal card carries its client's colour: a hairline of it along the
   top that brightens on hover, and the border takes the colour too. */
.p-card::before {
  content: ''; position: absolute; top: 0; inset-inline: 0; height: 3px;
  background: var(--c, var(--mg)); opacity: .55; transition: opacity .25s, height .25s var(--ease);
}
.p-card:hover::before { opacity: 1; height: 4px; }
.p-card:hover { border-color: color-mix(in srgb, var(--c, var(--mg)) 55%, var(--line)); }
.p-card h3 { transition: color .2s; }
.p-card:hover h3 { color: color-mix(in srgb, var(--c, var(--mg)) 35%, var(--mg)); }

/* The sidebar wears the brand's dashed rings, faintly, behind the user. */
.side { overflow: hidden; }
.side::after {
  content: ''; position: absolute; width: 380px; height: 380px; border-radius: 50%;
  bottom: -190px; inset-inline-start: -160px; pointer-events: none;
  border: 2px dashed rgba(255,255,255,.14);
  animation: side-spin 90s linear infinite;
}
.side::before {
  content: ''; position: absolute; width: 300px; height: 300px; border-radius: 50%;
  bottom: -150px; inset-inline-start: -120px; pointer-events: none;
  border: 2px dashed rgba(255,255,255,.08);
  animation: side-spin 60s linear infinite reverse;
}
@keyframes side-spin { to { transform: rotate(360deg); } }
.side > * { position: relative; z-index: 1; }
.side-nav button.is-on { box-shadow: 0 8px 20px -12px rgba(0,0,0,.5); }
.side-nav button { transition: background .2s, color .2s, transform .3s var(--snap); }
.side-nav button:hover { transform: translateX(-2px); }
.side-nav button.is-on:hover { transform: none; }

/* Empty states breathe a little. */
.empty svg { animation: float 4s ease-in-out infinite; }
@keyframes float { 50% { transform: translateY(-5px); } }

/* Primary buttons carry the same slow sheen as the export button. */
.btn-primary { position: relative; overflow: hidden; }
.btn-primary::after {
  content: ''; position: absolute; top: 0; bottom: 0; width: 40%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.22), transparent);
  transform: translateX(-180%); pointer-events: none;
}
.btn-primary:hover:not(:disabled)::after { animation: btn-sheen .85s var(--ease); }

/* Inputs lift a touch on focus. */
.input:focus, .select:focus, .textarea:focus { transform: translateY(-1px); }
.input, .select, .textarea { transition: border-color .2s, box-shadow .2s, transform .2s var(--ease); }

/* Modals arrive with a gentle overshoot; the backdrop blur eases in with it. */
.modal { transform: translateY(18px) scale(.975); transition: transform .38s var(--snap); }
.modal-bg { transition: opacity .28s, visibility .28s, backdrop-filter .28s; }

/* Switches spring. */
.switch i::before { transition: transform .35s var(--snap); }

@media (prefers-reduced-motion: reduce) {
  .page.is-enter, .tb-title h2, .tb-title .sub, .tb-today, .p-card, .mod-row, .tpl, .tbl-a tbody tr, .stat-tile, .fld-group, .pk-card, .empty svg, .side::before, .side::after, .btn-primary::after { animation: none !important; }
}

/* ====================================================== PUBLISH / LINKS  */

/* The public address on a proposal card. A filled dot means live. */
.p-link {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px; border-radius: var(--r-md);
  background: var(--bg); border: 1px solid var(--line-2);
}
.p-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--gray); }
.p-link.is-live .p-dot { background: var(--ok); box-shadow: 0 0 0 3px rgba(15,138,106,.18); }
.p-link.is-off  .p-dot { background: var(--warn); }
.p-link.is-none .p-dot { background: var(--line); }
.p-url { color: var(--mg); text-decoration: none; font-size: 12.5px; }
.p-url:hover { text-decoration: underline; }
.p-link.is-off .p-url { color: var(--gray); text-decoration: line-through; }

/* A URL reads left to right whatever the page direction is, so the origin
   chip belongs on the left and the slug box to its right. Inheriting the RTL
   page direction put them the other way round. */
.slug-row { display: flex; align-items: center; gap: 0; direction: ltr; }
.slug-pre {
  padding: 10px 11px; border: 1px solid var(--line); border-inline-end: 0;
  border-radius: var(--r-md) 0 0 var(--r-md);
  background: var(--bg); color: var(--gray); font-size: 12.5px; white-space: nowrap;
}
.slug-row .input { border-radius: 0 var(--r-md) var(--r-md) 0; }

/* Live-address badge in the editor topbar. */
.live-tag {
  display: inline-flex; align-items: center; gap: 5px;
  text-decoration: none; color: var(--mg); font-size: 12px;
}
.live-tag i { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); flex: none; }
.live-tag.is-off { color: var(--gray); }
.live-tag.is-off i { background: var(--warn); }
.live-tag:hover { text-decoration: underline; }

/* Module picker inside the editor. */
.mod-pick {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 11px 13px; border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--card); cursor: pointer; font: inherit; color: inherit;
  transition: border-color .2s, transform .3s var(--snap), background .2s;
}
.mod-pick:hover:not(:disabled) { border-color: var(--mg); transform: translateX(-3px); }
.mod-pick:disabled { opacity: .55; cursor: default; }
.mod-pick b { display: block; font-size: 13px; }
.mod-pick small { display: block; font-size: 11px; color: var(--gray); }

/* ============================================================== BRIEF     */

/* One headline and at most four findings. A dashboard that needs scrolling to
   reach its own conclusion is not a conclusion. */
.brief {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg);
  margin-bottom: 20px; overflow: hidden;
}
.brief-head {
  display: flex; align-items: center; gap: 11px;
  padding: 16px 20px; background: var(--mg); color: #fff;
}
.brief-head b { font-family: var(--f-body); font-weight: 600; font-size: 13.5px; line-height: 1.8; }
.brief-ico { flex: none; opacity: .75; }
.brief-ico svg { width: 18px; height: 18px; }

.brief-list { list-style: none; margin: 0; padding: 0; }
.brief-item {
  padding: 15px 20px 15px 20px; border-bottom: 1px solid var(--line-2);
  border-inline-start: 3px solid var(--line);
}
.brief-item:last-child { border-bottom: 0; }
.brief-item.is-warn { border-inline-start-color: var(--red); }
.brief-item.is-good { border-inline-start-color: var(--ok); }
.brief-item.is-info { border-inline-start-color: var(--mg-3); }
.brief-t { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.brief-t b { font-family: var(--f-body); font-weight: 600; font-size: 13.5px; flex: 1; }
.brief-item p { margin: 0; font-size: 12.5px; color: var(--gray); line-height: 1.95; }
.brief-do {
  margin-top: 6px !important; color: var(--mg) !important;
  padding-inline-start: 16px; position: relative;
}
.brief-do::before {
  content: '←'; position: absolute; inset-inline-start: 0; opacity: .55;
}

/* ============================================================ ANALYTICS  */

.stat-row {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 14px; margin-bottom: 20px;
}
.stat-tile {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 18px; display: grid; gap: 4px; position: relative; overflow: hidden;
}
.stat-tile::after {
  content: ''; position: absolute; top: 0; inset-inline-end: 0;
  width: 46px; height: 4px; background: var(--mg); border-end-start-radius: 4px;
}
.stat-ico { color: var(--mg); opacity: .5; }
.stat-ico svg { width: 20px; height: 20px; }
.stat-val { font-family: var(--f-title); font-size: 30px; color: var(--mg); line-height: 1.1; }
.stat-lab { font-size: 12px; color: var(--gray); }

.an-grid { display: grid; grid-template-columns: 1fr; gap: 16px; }
@media (min-width: 1100px) {
  .an-grid { grid-template-columns: 1fr 1fr; }
  .an-grid > :first-child { grid-column: 1 / -1; }
}
.an-card { overflow: hidden; }
.an-head { padding: 14px 18px; border-bottom: 1px solid var(--line); }
.an-head b { font-family: var(--f-title); font-size: 14px; color: var(--mg); }
.an-body { padding: 16px 18px; }
.an-scroll { max-height: 330px; overflow-y: auto; }

.an-row {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 0; border-bottom: 1px solid var(--line-2); font-size: 12.5px;
}
.an-row:last-child { border-bottom: 0; }
.an-row b { display: block; font-size: 12.5px; font-family: var(--f-body); font-weight: 600; }
.an-row small { display: block; font-size: 10.5px; }
.an-dev {
  background: var(--bg); border-radius: 100px; padding: 2px 9px;
  font-size: 10.5px; color: var(--mg); flex: none;
}
.an-meta { color: var(--gray); font-size: 11.5px; white-space: nowrap; }

/* Daily views */
.spark { display: flex; align-items: flex-end; gap: 3px; height: 120px; }
.spark-b { flex: 1; display: flex; align-items: flex-end; height: 100%; min-width: 3px; }
.spark-b i {
  width: 100%; background: linear-gradient(180deg, var(--mg-3), var(--mg));
  border-radius: 3px 3px 0 0; transition: opacity .2s;
}
.spark-b:hover i { opacity: .7; }
.spark-x { display: flex; justify-content: space-between; margin-top: 8px; font-size: 10.5px; color: var(--gray); }

/* Per-slide drop-off */
.fall { display: grid; gap: 6px; max-height: 52vh; overflow-y: auto; padding-inline-end: 4px; }
.fall-row { display: grid; grid-template-columns: 26px minmax(90px, 1.4fr) 3fr 44px 58px; gap: 10px; align-items: center; }
.fall-n { font-family: var(--f-title); color: var(--red); font-size: 12px; }
.fall-t { font-size: 12px; }
.fall-bar { height: 9px; background: var(--bg); border-radius: 100px; overflow: hidden; }
.fall-bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--mg), var(--mg-3)); border-radius: 100px; }
.fall-p { font-family: var(--f-title); font-size: 12px; color: var(--mg); text-align: end; }

@media (max-width: 620px) {
  .fall-row { grid-template-columns: 22px 1fr 40px; }
  .fall-bar, .fall-s { display: none; }
}

/* ------------------------------------------------------- notes / ranks  */

.note:last-child { border-bottom: 0; }

.rank-l { font-size: 12.5px; }
.rank-v { font-family: var(--f-title); font-size: 13px; color: var(--mg); white-space: nowrap; }
.rank-v small { font-family: var(--f-body); font-size: 10px; color: var(--gray); margin-inline-start: 3px; }

/* ------------------------------------------------------------ heatmap  */

.dd-top { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 16px; }

/* --------------------------------------------------- per-viewer analysis */

/* Excluding the team's own reads is a switch, not a buried setting: it changes
   every number on the page, so it belongs where the numbers are. */
.an-filter {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 5px 12px 5px 8px; background: var(--card); font-size: 12.5px;
  transition: border-color .2s, background .2s;
}
.an-filter:hover { border-color: var(--mg); }
.an-filter.is-on { border-color: var(--mg); background: rgba(61,16,97,.05); color: var(--mg); }
.an-filter b { font-family: var(--f-title); }
.an-filter .switch { width: 34px; height: 20px; }
.an-filter .switch i::before { width: 14px; height: 14px; }
.an-filter .switch input:checked + i::before { transform: translateX(-14px); }

.dd-scope {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding: 10px 0 14px; margin-bottom: 14px; border-bottom: 1px solid var(--line-2);
}
.dd-sep { width: 1px; height: 20px; background: var(--line); margin: 0 4px; }
.dd-tab {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--line); background: var(--card); color: var(--mg-ink);
  border-radius: 100px; padding: 5px 12px; cursor: pointer; font-size: 12.5px;
  transition: border-color .2s, background .2s, color .2s;
}
.dd-tab:hover { border-color: var(--mg); }
.dd-tab.is-on { background: var(--mg); border-color: var(--mg); color: #fff; }
.dd-tab b { font-family: var(--f-title); font-size: 11.5px; opacity: .75; }
.dd-tab svg { width: 13px; height: 13px; opacity: .6; }
.dd-who { max-width: 230px; }
.dd-who span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The mark that says "this one is us" — the reason the averages were wrong. */
.dd-who.is-internal { border-inline-start: 3px solid var(--red); }
.dd-who.is-client { border-inline-start: 3px solid var(--ok); }

.dd-who-card {
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--bg); padding: 14px; margin-bottom: 18px;
}
.dd-who-top { display: flex; align-items: flex-start; gap: 11px; }
.dd-who-ico {
  width: 34px; height: 34px; border-radius: 50%; flex: none;
  display: grid; place-items: center; background: var(--card);
  border: 1px solid var(--line); color: var(--mg);
}
.dd-who-ico svg { width: 17px; height: 17px; }
.dd-name { font-family: var(--f-title); font-size: 14px; }
.dd-who-top .hint { display: block; font-size: 11.5px; color: var(--gray); margin-top: 5px; line-height: 1.9; }
.dd-who-kind { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }
.dd-who-note { flex: 1; min-width: 160px; text-align: end; }
.dd-legend { display: flex; align-items: center; gap: 9px; margin-bottom: 8px; font-size: 12px; color: var(--mg); }
.heat-scale { display: inline-flex; gap: 2px; }
.heat-scale i { width: 16px; height: 9px; border-radius: 2px; background: var(--mg); }
.heat-scale i:nth-child(1) { opacity: .12; }
.heat-scale i:nth-child(2) { opacity: .32; }
.heat-scale i:nth-child(3) { opacity: .55; }
.heat-scale i:nth-child(4) { opacity: .78; }
.heat-scale i:nth-child(5) { opacity: 1; }

/* One cell per slide, shaded by how long readers stayed on it. */
.heat { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 20px; }
.heat-c {
  width: 34px; height: 34px; border-radius: 8px; display: grid; place-items: center;
  background: color-mix(in srgb, var(--mg) calc(var(--h) * 100%), #EFEAF4);
  color: color-mix(in srgb, #fff calc(var(--h) * 100%), var(--mg));
  font-family: var(--f-title); font-size: 11.5px; cursor: default;
  transition: transform .25s var(--snap);
}
.heat-c:hover { transform: translateY(-3px) scale(1.08); }

.dd-h { font-size: 14px; color: var(--mg); margin: 20px 0 10px; }

@media (max-width: 620px) {
      .heat-c { width: 28px; height: 28px; font-size: 10.5px; }
}

/* ------------------------------------------------------ analytics v2  */

/* The whole page is drawn from one hue for data, ink for text, and status
   colours only where they mean a state. Every mark has a hover tip. */
.an-bar { gap: 12px; }
.an-range button { padding: 6px 14px; }
.an-loading { opacity: .55; pointer-events: none; transition: opacity .25s; }
#anBody { transition: opacity .25s; }

.an-kpi { padding-bottom: 0; }
.an-kpi .stat-lab { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.an-delta {
  display: inline-flex; align-items: center; gap: 3px;
  border-radius: 100px; padding: 1px 8px; font-size: 11px; font-weight: 700;
  font-family: var(--f-body);
}
.an-delta.is-up { background: rgba(15,138,106,.11); color: var(--ok); }
.an-delta.is-down { background: rgba(208,34,68,.1); color: var(--red); }
.an-delta.is-flat { background: #F0EDF4; color: var(--gray); }
.an-spark { display: block; width: calc(100% + 36px); height: 34px; margin: 8px -18px 0; }
.an-spark-a { fill: rgba(61,16,97,.09); }
.an-spark-l { fill: none; stroke: var(--mg-3); stroke-width: 1.6; vector-effect: non-scaling-stroke; }

.an-tip {
  position: fixed; top: 0; left: 0; z-index: 300; pointer-events: none;
  background: var(--mg-ink); color: #fff; border-radius: 10px; padding: 8px 12px;
  font-size: 12px; line-height: 1.8; white-space: nowrap; box-shadow: var(--shadow-lg);
  translate: -50% -100%; opacity: 0; transition: opacity .15s var(--ease);
  will-change: transform;
}
.an-tip.is-on { opacity: 1; }
.an-tip b { font-family: var(--f-body); font-weight: 700; }
.an-tip .tech { font-size: 10.5px; opacity: .7; }

.an-main { margin-bottom: 16px; }
.an-legend { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--gray); margin-inline-start: 14px; }
.an-legend i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.an-legend .an-legend-line { width: 16px; height: 2px; border-radius: 2px; background: var(--red); margin-inline-start: 8px; }

.an-chart { width: 100%; height: auto; display: block; overflow: visible; }
.an-grid { stroke: var(--line-2); stroke-width: 1; }
.an-ax { fill: var(--gray); font-size: 10.5px; font-family: var(--f-body); }
.an-bar { fill: var(--mg); opacity: .82; transition: opacity .2s; transform-origin: bottom; transform-box: fill-box; }
.an-hit { fill: transparent; }
.an-hit:hover + *, .an-hit:hover { fill: rgba(61,16,97,.05); }
.an-line { fill: none; stroke: var(--red); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.an-dot { fill: #fff; stroke: var(--red); stroke-width: 1.6; }
/* The bars grow from the baseline in reading order when the chart lands. */
.an-bars .an-bar { animation: an-grow .6s var(--ease) backwards; animation-delay: calc(var(--k, 0) * 8ms); }
@keyframes an-grow { from { transform: scaleY(0); } }
.an-line { stroke-dasharray: 2000; stroke-dashoffset: 2000; animation: an-draw 1.4s var(--ease) .2s forwards; }
@keyframes an-draw { to { stroke-dashoffset: 0; } }

.an-grid3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; margin-bottom: 16px; }
@media (max-width: 1100px) { .an-grid3 { grid-template-columns: 1fr; } }
.an-card + .an-card, .an-grid3 + .an-card { margin-top: 16px; }

.an-donut { display: flex; align-items: center; gap: 18px; }
.an-ring { width: 128px; height: 128px; flex: none; }
.an-seg { transition: opacity .2s, stroke-width .2s; cursor: default; }
.an-ring:hover .an-seg { opacity: .35; }
.an-ring .an-seg:hover { opacity: 1; stroke-width: 15; }
.an-ring-v { font-family: var(--f-title); font-size: 20px; fill: var(--mg); }
.an-ring-l { font-size: 9.5px; fill: var(--gray); font-family: var(--f-body); }
.an-keys { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; flex: 1; min-width: 0; }
.an-keys li { display: flex; align-items: center; gap: 8px; font-size: 12.5px; }
.an-keys i { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.an-keys b { font-family: var(--f-title); color: var(--mg); }
.an-keys small { color: var(--gray); font-size: 11px; min-width: 34px; text-align: end; }

.an-hbars { display: grid; gap: 9px; }
.an-hbar { display: grid; grid-template-columns: minmax(70px, 34%) 1fr 40px; align-items: center; gap: 10px; font-size: 12.5px; border-radius: 8px; }
.an-hbar-l { color: var(--mg-ink); }
.an-hbar-t { height: 9px; background: var(--line-2); border-radius: 100px; overflow: hidden; }
.an-hbar-t i { display: block; height: 100%; background: var(--mg); border-radius: 100px; opacity: .85; transform-origin: 100% 50%; animation: an-widen .7s var(--ease) backwards; animation-delay: calc(var(--k, 0) * 40ms); }
.an-hbar-t i.is-full { background: var(--ok); }
@keyframes an-widen { from { transform: scaleX(0); } }
.an-hbar-v { font-family: var(--f-title); color: var(--mg); text-align: end; font-size: 12px; }
.an-hbar:hover .an-hbar-t i { opacity: 1; }

/* Weekday × hour */
.an-heat { display: grid; gap: 3px; overflow-x: auto; padding-bottom: 2px; }
.an-heat-row { display: grid; grid-template-columns: 62px repeat(24, minmax(12px, 1fr)); gap: 3px; align-items: center; }
.an-heat-row > span { font-size: 11px; color: var(--gray); white-space: nowrap; }
.an-heat-row > i {
  aspect-ratio: 1; border-radius: 4px; min-height: 12px;
  background: color-mix(in srgb, var(--mg) calc(var(--h, 0) * 100%), var(--line-2));
  transition: transform .2s var(--snap), box-shadow .2s;
}
.an-heat-row > i:hover { transform: scale(1.25); box-shadow: 0 2px 8px rgba(61,16,97,.25); position: relative; z-index: 1; }
.an-heat-x > i { aspect-ratio: auto; background: none; font-style: normal; font-size: 10px; color: var(--gray); text-align: center; min-height: 14px; }

/* Performance table */
.an-tbl-wrap { border: 0; border-radius: 0; }
.an-perf th { white-space: nowrap; }
.an-th { cursor: pointer; user-select: none; transition: color .15s; }
.an-th:hover, .an-th.is-on { color: var(--mg); }
.an-th i { font-style: normal; display: inline-block; width: 12px; font-size: 11px; opacity: .7; }
.an-perf tbody tr { transition: background .15s; animation: an-row .4s var(--ease) backwards; animation-delay: calc(var(--k, 0) * 30ms); }
.an-perf tbody tr:hover { background: var(--bg); }
@keyframes an-row { from { opacity: 0; transform: translateY(6px); } }
.an-pname { display: flex; align-items: center; gap: 10px; min-width: 200px; }
.an-pname b { font-family: var(--f-body); font-weight: 600; display: block; }
.an-pname small { display: block; font-size: 11px; }
.an-psw {
  width: 30px; height: 30px; border-radius: 9px; flex: none; display: grid; place-items: center; overflow: hidden;
  background: color-mix(in srgb, var(--c) 14%, #fff); border: 1px solid color-mix(in srgb, var(--c) 30%, #fff);
}
.an-psw::before { content: ''; width: 10px; height: 10px; border-radius: 3px; background: var(--c); }
.an-psw img { width: 100%; height: 100%; object-fit: contain; padding: 4px; position: absolute; background: #fff; }
.an-psw { position: relative; }
.an-psw-sm { width: 22px; height: 22px; border-radius: 6px; }
.an-psw-sm::before { width: 7px; height: 7px; }
.an-cell-bar { display: inline-flex; align-items: center; gap: 8px; min-width: 90px; }
.an-cell-bar i { display: block; height: 6px; border-radius: 100px; background: var(--mg); opacity: .35; flex: 1; max-width: 70px; min-width: 2px; }
.an-cell-bar b { font-family: var(--f-title); color: var(--mg); }
.an-meter { display: inline-block; width: 70px; height: 7px; border-radius: 100px; background: var(--line-2); overflow: hidden; vertical-align: middle; margin-inline-end: 6px; }
.an-meter i { display: block; height: 100%; background: var(--mg-3); border-radius: 100px; }
.an-meter.is-ok i { background: var(--ok); }
.an-meter-w { width: 56px; flex: none; }
.an-devbar { display: inline-flex; width: 70px; height: 7px; border-radius: 100px; overflow: hidden; gap: 2px; background: var(--line-2); vertical-align: middle; }
.an-devbar i { display: block; height: 100%; }

.an-row { animation: an-row .4s var(--ease) backwards; animation-delay: calc(var(--k, 0) * 25ms); }
.an-row .an-meta { min-width: 62px; text-align: end; }
.brief-item { animation: an-row .45s var(--ease) backwards; animation-delay: calc(var(--k, 0) * 60ms); }
.an-kpis .stat-tile { animation: an-row .5s var(--ease) backwards; }
.an-kpis .stat-tile:nth-child(2) { animation-delay: 50ms; }
.an-kpis .stat-tile:nth-child(3) { animation-delay: 100ms; }
.an-kpis .stat-tile:nth-child(4) { animation-delay: 150ms; }
.stat-tile { transition: transform .35s var(--snap), box-shadow .3s; }
.stat-tile:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }

.fall-row.is-drop .fall-bar i { background: linear-gradient(90deg, var(--red), #F26A84); }
.fall-row.is-drop .fall-p { color: var(--red); }
.heat-c { animation: an-row .4s var(--ease) backwards; animation-delay: calc(var(--k, 0) * 12ms); }
.fall-bar i { animation: an-widen .7s var(--ease) backwards; animation-delay: calc(var(--k, 0) * 18ms); transform-origin: 100% 50%; }

@media (prefers-reduced-motion: reduce) {
  .an-bars .an-bar, .an-line, .an-hbar-t i, .an-perf tbody tr, .an-row, .brief-item, .an-kpis .stat-tile, .heat-c, .fall-bar i { animation: none !important; stroke-dashoffset: 0; }
}

/* ================================================================= TABLES  */

.tbl-a { width: 100%; border-collapse: collapse; background: var(--card); border-radius: var(--r-lg); overflow: hidden; }
.tbl-a th { background: var(--bg); font-size: 12px; font-weight: 600; color: #5B4A6E; padding: 11px 14px; text-align: start; border-bottom: 1px solid var(--line); }
.tbl-a td { padding: 12px 14px; border-bottom: 1px solid var(--line-2); font-size: 13px; }
.tbl-a tr:last-child td { border-bottom: 0; }
.tbl-scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r-lg); }

/* --------------------------------------------------------------- loading  */

.spin { width: 17px; height: 17px; border: 2px solid rgba(255,255,255,.35); border-top-color: #fff; border-radius: 50%; animation: spin .7s linear infinite; }
.btn:not(.btn-primary):not(.btn-export) .spin { border-color: rgba(61,16,97,.25); border-top-color: var(--mg); }
@keyframes spin { to { transform: rotate(360deg); } }

.skeleton { background: linear-gradient(90deg, var(--line-2) 25%, #F7F4FA 50%, var(--line-2) 75%); background-size: 200% 100%; animation: sk 1.4s infinite; border-radius: var(--r-md); }
@keyframes sk { to { background-position: -200% 0; } }

/* ==========================================================================
   Live slide canvas
   The slide is edited on itself, so the canvas is the whole right-hand side:
   a thin bar of controls over a frame that renders at true device size and is
   scaled to fit. Scaling rather than reflowing is what makes the preview
   honest — 14px type in the frame is 14px type for the client.
   ========================================================================== */

.editor-live { grid-template-columns: 300px 1fr; }
.ed-canvas { min-width: 0; min-height: 0; display: grid; background: #EFEAF4; }

/* `height: 100%` matters: the stage is the `1fr` row, and without a height to
   divide up it resolves to zero and the frame has nowhere to be. */
.lv { display: grid; grid-template-rows: auto 1fr; height: 100%; min-height: 0; min-width: 0; }
.lv-bar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 9px 14px; background: var(--card);
  border-bottom: 1px solid var(--line);
}
.lv-kind {
  font-family: var(--f-title); font-size: 13.5px; color: var(--mg);
  background: rgba(61,16,97,.07); border-radius: 100px; padding: 3px 12px; white-space: nowrap;
}
.lv-tip { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lv-opts { display: flex; gap: 6px; }
.lv-opt { gap: 5px; }
.lv-opt b { color: var(--mg); font-family: var(--f-body); font-weight: 600; }
.lv-dev { flex: none; }

.lv-stage { position: relative; overflow: hidden; min-height: 0; }
/* Positioned from the top-left corner and pulled back by half its own size:
   the frame keeps its true pixel dimensions and only the transform scales it,
   which is what keeps the preview truthful about type size. */
.lv-frame {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%) scale(1);
  transform-origin: center center;
  border: 0; border-radius: 6px; background: #fff;
  box-shadow: 0 30px 70px -30px rgba(61,16,97,.55);
}

.lv-empty {
  position: absolute; inset: 0; display: grid; align-content: center; justify-items: center;
  gap: 8px; text-align: center; color: var(--gray); background: #EFEAF4;
}
.lv-empty svg { width: 40px; height: 40px; opacity: .4; }
.lv-empty h3 { font-size: 15px; color: var(--mg); }
.lv-empty p { margin: 0; font-size: 12.5px; max-width: 34ch; line-height: 2; }

/* The studio is the same canvas inside a dialog. */
.studio {
  display: grid; height: min(66vh, 620px); min-height: 0;
  border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden;
}
.studio .lv-bar { border-radius: var(--r-md) var(--r-md) 0 0; }
.studio .lv-stage { background: #EFEAF4; }

/* ------------------------------------------------------------ slide popup */

.pv-wrap { display: grid; gap: 10px; }
.pv-sub { margin: 0; }
.pv-stage { position: relative; overflow: hidden; border-radius: var(--r-md); background: #EFEAF4; }
.pv-frame {
  width: 1440px; height: 810px; border: 0; display: block;
  transform-origin: top right;
  box-shadow: 0 20px 50px -28px rgba(61,16,97,.5);
}

/* ========================================================== slide picker */

/* A gallery of thirty-one layouts wants more room than a form dialog. */
.modal:has(.pk-grid) { width: min(1180px, 100%); }
.modal:has(.pk-grid) .pk-head { position: sticky; top: 61px; z-index: 1; background: var(--card); padding-bottom: 12px; }

.pk-head { display: grid; gap: 12px; margin-bottom: 16px; }
.pk-search { max-width: none; }
.pk-head .pick-cats { margin: 0; }

.pk-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(216px, 1fr)); gap: 14px;
}
.pk-card {
  border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden;
  background: var(--card); transition: border-color .2s, transform .2s var(--ease), box-shadow .2s;
}
.pk-card:hover { border-color: var(--mg); transform: translateY(-3px); box-shadow: var(--shadow-lg); }

.pk-hit { display: block; width: 100%; padding: 0; border: 0; background: none; cursor: pointer; }
.pk-thumb {
  display: block; position: relative; overflow: hidden;
  height: var(--pk-h, 122px); background: var(--bg);
}
.pk-frame {
  position: absolute; top: 0; right: 0;
  width: 1440px; height: 810px; border: 0;
  transform: scale(var(--pk-scale, .16));
  transform-origin: top right;
  pointer-events: none;                 /* the card handles the click */
  opacity: 0; transition: opacity .35s var(--ease);
}
.pk-card.is-live .pk-frame { opacity: 1; }
.pk-card.is-live .pk-skel { opacity: 0; }
.pk-skel {
  position: absolute; inset: 0; transition: opacity .35s;
  background: linear-gradient(90deg, var(--line-2) 25%, #F7F4FA 50%, var(--line-2) 75%);
  background-size: 200% 100%; animation: sk 1.4s infinite;
}

.pk-foot { display: flex; align-items: center; gap: 7px; padding: 9px 11px; border-top: 1px solid var(--line-2); }
.pk-foot b { font-family: var(--f-body); font-weight: 600; font-size: 12.5px; flex: 1; min-width: 0; }
.pk-foot .chip { font-size: 10px; padding: 2px 7px; }
.pk-eye { opacity: 0; transition: opacity .2s; flex: none; }
.pk-card:hover .pk-eye, .pk-eye:focus-visible { opacity: 1; }
.pk-empty { text-align: center; padding: 40px 0; }

/* A slide row shared by the module editor, its preview list and templates. */
.slide-row { display: flex; align-items: center; gap: 8px; }
.slide-row b { font-size: 12.5px; display: block; }
.slide-row small { font-size: 10.5px; display: block; }

/* Narrow: the editor panes become tabs. */
.ed-mobtabs { display: none; }
@media (max-width: 1180px) {
  /* Exactly one pane is on screen here, and it takes the whole height. With an
     `auto` row the structure list — thirty-odd slides tall — claimed all of it
     and left the canvas at zero. */
  .editor { grid-template-columns: 1fr; grid-template-rows: 1fr; height: calc(100vh - 65px); }
  .editor-live { grid-template-columns: 1fr; }
  .ed-mobtabs { display: flex; gap: 4px; padding: 9px 14px; border-bottom: 1px solid var(--line); background: var(--card); overflow-x: auto; }
  .ed-col { border-left: 0; }
  .editor > .ed-col, .editor > .ed-canvas { display: none; }
  .editor > .ed-col.is-shown { display: grid; }
  .editor > .ed-canvas.is-shown { display: grid; }
}
@media (max-width: 760px) {
  .lv-tip { display: none; }
  .lv-dev { display: none; }
  .studio { height: 70vh; }
}
@media (max-width: 620px) {
  .pk-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
}

/* Viewer chips in the drill-down never wrap, and the fold keeps the bar short. */
.dd-who { white-space: nowrap; }
.dd-who b { white-space: nowrap; }
.dd-more { border-style: dashed; color: var(--gray); }
.dd-more:hover { color: var(--mg); }

/* ==========================================================================
   DASHBOARD v2: the login page's language, everywhere.
   One card on a quiet field. The sidebar is the brand stage (purple, grain,
   the dashed rings turning behind the mark), the work area is white with a
   soft light under the pointer. Pills for buttons, floating fields, soft
   shadows, and every list still arrives one row after another. Written as
   an overlay on the rules above, so nothing about how a page works changes;
   only how it looks and moves.
   ========================================================================== */

body.dash-page { background: #F3EFF7; --lp: clamp(10px, 1.6vw, 22px); overflow: hidden; }
.mg-field { position: fixed; inset: 0; pointer-events: none; overflow: hidden; z-index: 0; }
.mg-glow { position: absolute; border-radius: 50%; filter: blur(60px); opacity: .5; }
.mg-glow-a { width: 42vw; height: 42vw; right: -12vw; top: -20vw; background: radial-gradient(circle, rgba(124,58,176,.32), rgba(124,58,176,0) 65%); }
.mg-glow-b { width: 36vw; height: 36vw; left: -10vw; bottom: -18vw; background: radial-gradient(circle, rgba(208,34,68,.18), rgba(208,34,68,0) 65%); }

body.dash-page .app {
  position: relative; z-index: 1;
  margin: var(--lp); height: calc(100vh - var(--lp) * 2); min-height: 0;
  grid-template-columns: 248px 1fr;
  border-radius: clamp(18px, 2.2vw, 28px); overflow: hidden; background: #fff;
  box-shadow: 0 40px 90px -40px rgba(27,10,46,.45), 0 2px 0 rgba(255,255,255,.6) inset;
  --mx: 0; --my: 0;
  animation: app-in .8s cubic-bezier(.19,.86,.32,1) backwards;
}
@keyframes app-in { from { opacity: 0; transform: translateY(16px) scale(.988); filter: blur(6px); } }

/* ---- the sidebar as the brand stage */
body.dash-page .side {
  position: relative; height: 100%; top: auto; overflow: hidden; isolation: isolate;
  background: radial-gradient(120% 80% at 90% 0%, #5A1B8C 0%, var(--mg) 42%, #2A0B45 100%);
  padding: 26px 18px 20px; gap: 8px;
}
body.dash-page .side::before, body.dash-page .side::after { display: none; }
.side-grain {
  position: absolute; inset: 0; z-index: 0; pointer-events: none; opacity: .26; mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .5 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}
.side-brand {
  position: relative; z-index: 1; margin: 4px 6px 30px; width: 132px;
  translate: calc(var(--mx) * 5px) calc(var(--my) * 4px);
  transition: translate .9s cubic-bezier(.19,.86,.32,1);
}
body.dash-page .side-logo { width: 100%; margin: 0; position: relative; z-index: 1; }
.side-rings {
  position: absolute; z-index: 0; pointer-events: none; color: #fff; opacity: .5;
  width: 300%; aspect-ratio: 1; left: 50%; top: 50%; translate: -50% -50%;
}
.side-rings svg { width: 100%; height: 100%; display: block; overflow: visible; }

body.dash-page .side-nav { gap: 4px; }
body.dash-page .side-nav button {
  padding: 11px 14px; border-radius: 14px; color: rgba(255,255,255,.7); font-size: 13.5px;
  transition: background .25s, color .25s, translate .35s var(--snap);
}
body.dash-page .side-nav button::before {
  inset-inline-start: 6px; width: 5px; height: 5px; border-radius: 50%; background: #F5B921;
  opacity: 0; transform: translateY(-50%) scale(.4); transition: opacity .25s, transform .35s var(--snap);
}
body.dash-page .side-nav button:hover { background: rgba(255,255,255,.08); color: #fff; transform: none; translate: -2px 0; }
body.dash-page .side-nav button:hover::before { height: 5px; opacity: .7; transform: translateY(-50%) scale(1); }
body.dash-page .side-nav button.is-on {
  background: rgba(255,255,255,.14); color: #fff; font-weight: 600;
  box-shadow: 0 1px 0 rgba(255,255,255,.14) inset, 0 10px 24px -16px rgba(0,0,0,.6);
  backdrop-filter: blur(6px);
}
body.dash-page .side-nav button.is-on::before { opacity: 1; height: 5px; transform: translateY(-50%) scale(1); }
body.dash-page .side-nav button.is-on:hover { translate: 0 0; }

body.dash-page .side-sep { background: rgba(255,255,255,.1); margin: 10px 4px; }
body.dash-page .side-user { padding: 10px 8px; border-radius: 16px; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.08); }
body.dash-page .side-av { width: 38px; height: 38px; box-shadow: 0 0 0 2px rgba(255,255,255,.14); }
.side-out {
  display: flex; align-items: center; gap: 9px; width: 100%;
  background: transparent; border: 1px solid rgba(255,255,255,.12); color: rgba(255,255,255,.72);
  padding: 9px 12px; border-radius: 999px; cursor: pointer; font-size: 12.5px;
  transition: background .25s, color .25s, border-color .25s;
}
.side-out svg { width: 15px; height: 15px; flex: none; }
.side-out:hover { background: rgba(255,255,255,.1); color: #fff; border-color: rgba(255,255,255,.22); }

/* ---- the work area */
body.dash-page .main { position: relative; height: 100%; overflow: auto; --sx: 50%; --sy: 50%; background: #fff; }
.main-spot {
  position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background: radial-gradient(560px circle at var(--sx) var(--sy), rgba(124,58,176,.06), transparent 62%);
  opacity: 0; transition: opacity .4s;
}
body.dash-page .main:hover .main-spot { opacity: 1; }
body.dash-page .topbar {
  position: sticky; top: 0; z-index: 30;
  padding: 26px clamp(20px, 3vw, 40px) 18px;
  background: linear-gradient(rgba(255,255,255,.96), rgba(255,255,255,.86));
  border-bottom: 1px solid var(--line-2); backdrop-filter: blur(14px);
}
.tb-eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 11px; color: var(--mg-3); letter-spacing: .04em; margin-bottom: 4px;
  animation: page-in .45s var(--ease) backwards;
}
.tb-eyebrow::before { content: ''; width: 18px; height: 2px; border-radius: 2px; background: var(--red); }
body.dash-page .topbar h2 { font-size: clamp(22px, 2vw, 28px); color: var(--mg-ink); letter-spacing: -.01em; }
body.dash-page .topbar .sub { font-size: 12.5px; }
body.dash-page .tb-today { display: inline-flex; align-items: center; gap: 8px; padding: 7px 14px; background: #FAF8FC; border-color: var(--line-2); color: #5B4A6E; font-size: 12px; }
.tb-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 3px rgba(15,138,106,.15); animation: tb-pulse 2.4s ease-in-out infinite; }
@keyframes tb-pulse { 50% { box-shadow: 0 0 0 5px rgba(15,138,106,.08); } }
body.dash-page .page { position: relative; z-index: 1; padding: clamp(20px, 3vw, 40px); padding-top: 24px; }

/* ---- primitives, restyled */
body.dash-page .btn { border-radius: 999px; padding: 9px 18px; border-color: var(--line); transition: background .22s, border-color .22s, color .22s, transform .3s var(--snap), box-shadow .3s, opacity .2s; }
body.dash-page .btn:hover:not(:disabled) { transform: translateY(-1px); }
body.dash-page .btn:active:not(:disabled) { transform: translateY(0); }
body.dash-page .btn-sm { padding: 6px 13px; }
body.dash-page .btn-icon { padding: 7px; width: 34px; height: 34px; border-radius: 50%; }
body.dash-page .btn-icon.btn-sm { width: 30px; height: 30px; padding: 6px; }
body.dash-page .btn-primary, body.dash-page .btn-export {
  background: linear-gradient(100deg, var(--mg-2), var(--mg) 55%, #2A0B45); border: 0; color: #fff;
  box-shadow: 0 12px 26px -14px rgba(61,16,97,.7), 0 1px 0 rgba(255,255,255,.18) inset;
}
body.dash-page .btn-primary:hover:not(:disabled), body.dash-page .btn-export:hover:not(:disabled) {
  background: linear-gradient(100deg, var(--mg-2), var(--mg) 55%, #2A0B45); filter: brightness(1.07);
  box-shadow: 0 18px 34px -16px rgba(61,16,97,.75), 0 1px 0 rgba(255,255,255,.22) inset; color: #fff;
}
body.dash-page .btn-primary::after, body.dash-page .btn-export::after { background: linear-gradient(100deg, transparent, rgba(255,255,255,.26), transparent); }
body.dash-page .btn-ghost { border-color: transparent; }
body.dash-page .btn-danger:hover:not(:disabled) { transform: translateY(-1px); }

body.dash-page .input, body.dash-page .select, body.dash-page .textarea {
  background: #FAF8FC; border-radius: 14px; padding: 11px 14px;
  transition: border-color .25s, box-shadow .25s, background .25s, transform .25s var(--ease);
}
body.dash-page .input:hover, body.dash-page .select:hover, body.dash-page .textarea:hover { border-color: #D9CFE6; }
body.dash-page .input:focus, body.dash-page .select:focus, body.dash-page .textarea:focus {
  background: #fff; border-color: var(--mg); box-shadow: 0 0 0 4px rgba(61,16,97,.08); transform: none;
}
body.dash-page .search .input { padding-right: 40px; border-radius: 999px; }
body.dash-page .search svg { right: 15px; }
body.dash-page .chip { border-radius: 999px; padding: 4px 11px; }

body.dash-page .card, body.dash-page .p-card, body.dash-page .mod-row, body.dash-page .tpl, body.dash-page .stat-tile, body.dash-page .tbl-scroll {
  border-radius: 20px; border-color: #EFEAF4;
  box-shadow: 0 12px 30px -24px rgba(27,10,46,.35);
}
body.dash-page .p-card { padding: 20px; }
body.dash-page .p-card:hover { box-shadow: 0 28px 50px -30px rgba(27,10,46,.5); }
body.dash-page .p-card::before { height: 3px; inset-inline: 20px; border-radius: 0 0 3px 3px; }
body.dash-page .p-swatch { border-radius: 14px; }
body.dash-page .p-actions { border-top-color: #F3EFF7; }
body.dash-page .tbl-a th { background: #FAF8FC; color: var(--mg-3); font-size: 11.5px; letter-spacing: .02em; padding: 12px 16px; }
body.dash-page .tbl-a td { padding: 13px 16px; }
body.dash-page .tbl-scroll { overflow: hidden; }
body.dash-page .tbl-scroll:has(.tbl-a) { overflow-x: auto; }
body.dash-page .empty svg { color: #D9CFE6; }

body.dash-page .modal-bg { backdrop-filter: blur(8px); background: rgba(27,10,46,.42); }
body.dash-page .modal { border-radius: 24px; box-shadow: 0 50px 100px -40px rgba(27,10,46,.6); }
body.dash-page .modal-head { border-radius: 24px 24px 0 0; border-bottom-color: var(--line-2); }
body.dash-page .modal-foot { border-top-color: var(--line-2); }
body.dash-page .toast { border-radius: 16px; }

/* Toolbars that open a page: the primary action sits with a breath of air. */
body.dash-page .toolbar-row { margin-bottom: 24px; gap: 12px; }

/* The editor is bare and owns the viewport inside the card. */
body.dash-page .editor { height: calc(100vh - var(--lp) * 2 - 65px); }

@media (max-width: 900px) {
  body.dash-page { overflow: auto; --lp: 0px; }
  body.dash-page .app { margin: 0; height: auto; min-height: 100vh; border-radius: 0; box-shadow: none; animation: none; grid-template-columns: 1fr; }
  body.dash-page .side { position: fixed; height: 100dvh; }
  body.dash-page .main { height: auto; overflow: visible; }
  body.dash-page .topbar { padding: 18px 18px 14px; }
  body.dash-page .editor { height: calc(100vh - 65px); }
}
@media (prefers-reduced-motion: reduce) {
  body.dash-page .app { animation: none; }
  .tb-dot, .tb-eyebrow { animation: none !important; }
  .side-brand { translate: 0 0 !important; }
}

/* ---- page change
   Three things at once, each cheap on its own: the leaving page (frozen,
   clipped to the viewport, on its own white ground so nothing shows through
   it) fades up and away; a band of light sweeps across the work area; the
   next page breathes in from soft focus through a warm flash, the way a
   slide's content does, and its rows follow on their ladder. Blur radii are
   small and layers are promoted only while they move. */
body.dash-page .page.is-pre { opacity: 0; visibility: hidden; }
/* Rows inside a page still off-screen hold their first frame until the reveal. */
body.dash-page .page.is-pre * { animation-play-state: paused !important; }

body.dash-page .page.is-leave {
  position: absolute; inset-inline: 0; z-index: 3; overflow: hidden; box-sizing: border-box;
  background: #fff;
  animation: page-out .46s cubic-bezier(.4,0,.2,1) forwards;
  transform-origin: 50% 0;
  will-change: transform, opacity;
}
@keyframes page-out {
  0%   { opacity: 1; transform: none; }
  100% { opacity: 0; transform: translateY(-14px) scale(.992); }
}

body.dash-page .page.is-enter {
  animation: page-cine .95s cubic-bezier(.16,.6,.22,1) backwards;
  transform-origin: 50% 0;
  will-change: transform, filter, opacity;
}
@keyframes page-cine {
  0%   { opacity: 0; transform: translateY(14px) scale(.985); filter: blur(4px) sepia(.5) brightness(1.08); }
  40%  { opacity: 1; filter: blur(1px) sepia(.5) brightness(1.12); }
  100% { opacity: 1; transform: none; filter: blur(0) sepia(0) brightness(1); }
}

/* The light: a soft diagonal band, brand-tinted at the edges and white at
   its core, crossing the work area right to left on the swap. Transform
   only, so it costs nothing. */
.main-wipe {
  position: absolute; inset: 0; z-index: 25; pointer-events: none; overflow: hidden;
  opacity: 0;
}
.main-wipe::before {
  content: ''; position: absolute; top: -30%; bottom: -30%; right: -60%; width: 60%;
  background: linear-gradient(100deg, transparent 0%, rgba(124,58,176,.06) 30%, rgba(255,255,255,.85) 50%, rgba(208,34,68,.05) 70%, transparent 100%);
  transform: skewX(-8deg);
}
body.dash-page .main.is-wipe .main-wipe { animation: wipe-fade .8s linear forwards; }
body.dash-page .main.is-wipe .main-wipe::before { animation: wipe-run .8s cubic-bezier(.65,0,.2,1) forwards; }
@keyframes wipe-fade { 0% { opacity: 0; } 15% { opacity: 1; } 85% { opacity: 1; } 100% { opacity: 0; } }
@keyframes wipe-run { to { transform: skewX(-8deg) translateX(-280%); } }

/* The title crossfades: the old one dips out while the page leaves, the new
   one rises in with the reveal. */
body.dash-page .topbar.is-swap .tb-title { opacity: 0; transform: translateY(-6px); transition: opacity .2s var(--ease), transform .25s var(--ease); }
body.dash-page .tb-title { transition: none; }
body.dash-page .tb-title h2, body.dash-page .tb-title .sub, body.dash-page .tb-eyebrow {
  animation: title-in .7s cubic-bezier(.16,.6,.22,1) backwards;
}
@keyframes title-in { from { opacity: 0; transform: translateY(10px); } }
body.dash-page .tb-eyebrow { animation-delay: .05s; }
body.dash-page .tb-title h2 { animation-delay: .1s; }
body.dash-page .tb-title .sub { animation-delay: .16s; }

@media (prefers-reduced-motion: reduce) {
  body.dash-page .page.is-enter, body.dash-page .page.is-leave, body.dash-page .tb-title h2, body.dash-page .tb-title .sub, body.dash-page .tb-eyebrow,
  body.dash-page .main.is-wipe .main-wipe, body.dash-page .main.is-wipe .main-wipe::before { animation: none !important; }
  body.dash-page .page.is-pre { opacity: 1; visibility: visible; }
  body.dash-page .topbar.is-swap .tb-title { opacity: 1; transform: none; }
}
