@font-face{font-family:'Hanken Grotesk';src:url('/assets/fonts/HankenGrotesk.ttf') format('truetype');font-weight:100 900;font-style:normal;font-display:swap}
@font-face{font-family:'JetBrains Mono';src:url('/assets/fonts/JetBrainsMono.ttf') format('truetype');font-weight:100 800;font-style:normal;font-display:swap}

/* zipka · raw color primitives — the only place literal hex values live.
   Discipline: a deep neutral ink scale + ONE primary accent (Klein Blue, the brand
   constant) + ONE warm "art" accent encoding the tech↔art duality + muted statuses.
   Semantic tokens (semantic.css) reference these; components reference semantics. */

:root {
  /* ---- Neutrals · cool near-black → paper ---- */
  --c-ink-900: #0E0E10;
  --c-ink-800: #121214; /* brand ink */
  --c-ink-700: #232327;
  --c-ink-600: #3A3A3F; /* ink-soft */
  --c-ink-500: #6C6C72; /* muted */
  --c-ink-400: #94949A;
  --c-ink-300: #C2C2C7;
  --c-ink-200: #DEDEE1;
  --c-ink-100: #ECECEE;
  --c-ink-50:  #F6F6F7; /* soft surface */
  --c-paper:   #FFFFFF;

  /* ---- Klein Blue · primary / "tech" accent ---- */
  --c-blue-700: #00227A; /* pressed */
  --c-blue-600: #002FA7; /* Klein — base */
  --c-blue-500: #1E47C8;
  --c-blue-400: #4D6FE0;
  --c-blue-300: #7E97EC; /* dark-theme accent */
  --c-blue-200: #B9C6EC;
  --c-blue-100: #E6EBF7; /* tint surface */

  /* ---- Vermilion · secondary / "art" accent ---- */
  --c-verm-700: #B8330F;
  --c-verm-600: #E1431B; /* base */
  --c-verm-500: #F2542D;
  --c-verm-300: #F4977E;
  --c-verm-100: #FBE7E0; /* tint surface */

  /* ---- Cobalt · alternate accent (voltage) ---- */
  --c-cobalt-700: #0F3DD6;
  --c-cobalt-600: #1F53FF;
  --c-cobalt-300: #7E9BFF;
  --c-cobalt-100: #E7ECFF;

  /* ---- Status ---- */
  --c-green-600: #157F3C;
  --c-green-300: #34C76A;
  --c-green-100: #E3F1E8;

  --c-amber-700: #8A5200;
  --c-amber-600: #B26B00; /* text-safe */
  --c-amber-fill: #F2A20C;
  --c-amber-300: #F2B33B;
  --c-amber-100: #FBEFD9;

  --c-red-700: #A81F14;
  --c-red-600: #D12B1E;
  --c-red-300: #FF6B5E;
  --c-red-100: #FBE7E5;
}

/* zipka · semantic tokens — what components actually reference.
   Light is the default on :root. Dark theme = [data-theme="dark"].
   Accent variants = [data-accent="cobalt"|"vermilion"] (default Klein).
   Combine freely, e.g. <html data-theme="dark" data-accent="cobalt">. */

:root {
  /* surfaces & text */
  --bg:            var(--c-paper);
  --surface:       var(--c-paper);
  --surface-2:     var(--c-ink-50);   /* soft fills, toolbars */
  --surface-sunken:var(--c-ink-100);
  --text:          var(--c-ink-800);
  --text-soft:     var(--c-ink-600);
  --text-muted:    var(--c-ink-500);
  --text-inverse:  var(--c-paper);

  /* lines — thin hairline vs full-ink */
  --line:          rgba(18,18,20,0.13);
  --line-2:        rgba(18,18,20,0.22);
  --line-strong:   var(--c-ink-800);

  /* primary accent (Klein) */
  --accent:        var(--c-blue-600);
  --accent-hover:  var(--c-blue-700);
  --accent-press:  var(--c-blue-700);
  --accent-contrast: var(--c-paper);
  --accent-tint:   var(--c-blue-100);
  --accent-line:   var(--c-blue-200);

  /* secondary "art" accent (vermilion) — used sparingly */
  --accent-2:       var(--c-verm-600);
  --accent-2-contrast: var(--c-paper);
  --accent-2-tint:  var(--c-verm-100);

  /* focus ring — always the live accent */
  --focus:         var(--accent);

  /* status: text, solid fill, tint surface */
  --success:       var(--c-green-600);
  --success-tint:  var(--c-green-100);
  --warning:       var(--c-amber-600);
  --warning-fill:  var(--c-amber-fill);
  --warning-tint:  var(--c-amber-100);
  --danger:        var(--c-red-600);
  --danger-tint:   var(--c-red-100);
  --info:          var(--accent);
  --info-tint:     var(--accent-tint);
}

/* ----------------------------------------------------------------- *
 * DARK THEME                                                         *
 * ----------------------------------------------------------------- */
[data-theme="dark"] {
  --bg:            var(--c-ink-900);
  --surface:       #161619;
  --surface-2:     #1D1D21;
  --surface-sunken:#0A0A0C;
  --text:          #F3F3F4;
  --text-soft:     #BFBFC4;
  --text-muted:    #8A8A90;
  --text-inverse:  var(--c-ink-900);

  --line:          rgba(255,255,255,0.14);
  --line-2:        rgba(255,255,255,0.24);
  --line-strong:   #F3F3F4;

  /* Klein is too dark on a dark ground — lift to a legible blue */
  --accent:        var(--c-blue-300);
  --accent-hover:  var(--c-blue-200);
  --accent-press:  var(--c-blue-400);
  --accent-contrast: var(--c-ink-900);
  --accent-tint:   rgba(126,151,236,0.16);
  --accent-line:   rgba(126,151,236,0.42);

  --accent-2:       var(--c-verm-300);
  --accent-2-contrast: var(--c-ink-900);
  --accent-2-tint:  rgba(244,151,126,0.16);

  --success:       var(--c-green-300);
  --success-tint:  rgba(52,199,106,0.15);
  --warning:       var(--c-amber-300);
  --warning-fill:  var(--c-amber-fill);
  --warning-tint:  rgba(242,179,59,0.15);
  --danger:        var(--c-red-300);
  --danger-tint:   rgba(255,107,94,0.15);
}

/* ----------------------------------------------------------------- *
 * ACCENT VARIANTS                                                    *
 * ----------------------------------------------------------------- */
[data-accent="cobalt"] {
  --accent:        var(--c-cobalt-600);
  --accent-hover:  var(--c-cobalt-700);
  --accent-press:  var(--c-cobalt-700);
  --accent-tint:   var(--c-cobalt-100);
  --accent-line:   #B9C6FF;
}
[data-accent="cobalt"][data-theme="dark"] {
  --accent:        var(--c-cobalt-300);
  --accent-hover:  #A9BEFF;
  --accent-press:  var(--c-cobalt-600);
  --accent-tint:   rgba(126,155,255,0.16);
  --accent-line:   rgba(126,155,255,0.42);
}

[data-accent="vermilion"] {
  --accent:        var(--c-verm-600);
  --accent-hover:  var(--c-verm-700);
  --accent-press:  var(--c-verm-700);
  --accent-tint:   var(--c-verm-100);
  --accent-line:   #F4BBAA;
  /* swap the secondary to Klein so the duality holds */
  --accent-2:       var(--c-blue-600);
  --accent-2-tint:  var(--c-blue-100);
}
[data-accent="vermilion"][data-theme="dark"] {
  --accent:        var(--c-verm-300);
  --accent-hover:  #F8B4A2;
  --accent-press:  var(--c-verm-600);
  --accent-tint:   rgba(244,151,126,0.16);
  --accent-line:   rgba(244,151,126,0.42);
  --accent-2:       var(--c-blue-300);
  --accent-2-tint:  rgba(126,151,236,0.16);
}

/* zipka · typography tokens.
   Monospace carries the brand: every heading, eyebrow, label, button and number is
   JetBrains Mono. Body copy is Hanken Grotesk. Weight tops out at 600 — Swiss
   restraint, no heavy/black weights. */

:root {
  --font-mono: 'JetBrains Mono', 'Roboto Mono', 'SF Mono', ui-monospace, Menlo, monospace;
  --font-sans: 'Hanken Grotesk', system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;
  --font-code: var(--font-mono);

  /* type scale — fluid where it spans hero→mobile */
  --text-display: clamp(34px, 6vw, 60px);
  --text-h1:      clamp(28px, 4.4vw, 44px);
  --text-h2:      clamp(24px, 3.6vw, 36px);
  --text-h3:      clamp(18px, 2vw, 22px);
  --text-lead:    clamp(17px, 2.2vw, 20px);
  --text-body:    16px;
  --text-sm:      14px;
  --text-xs:      12px;
  --text-eyebrow: 12px;

  /* weights */
  --fw-regular:  400; /* @kind font */
  --fw-medium:   500; /* @kind font */
  --fw-semibold: 600; /* @kind font */

  /* line-heights */
  --lh-tight: 1.12; /* @kind font */
  --lh-snug:  1.3;  /* @kind font */
  --lh-body:  1.65; /* @kind font */

  /* tracking */
  --tracking-tight:   -0.01em;
  --tracking-eyebrow: 0.06em;
  --tracking-mono:    0;
}

/* zipka · spacing, borders, radius, layout, motion.
   Two hard brand rules live here: radius is ALWAYS 0 (sharp corners everywhere) and
   shadow is ALWAYS none (depth comes from hairline borders, never elevation). */

:root {
  /* 4px spacing scale */
  --space-0:  0;
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  20px;
  --space-6:  24px;
  --space-7:  32px;
  --space-8:  40px;
  --space-9:  48px;
  --space-10: 64px;
  --space-11: 80px;
  --space-12: 96px;

  /* borders & radius — the brutalist constants */
  --border-w:        1px;
  --border-w-strong: 1.5px;
  --radius:   0;   /* never round */
  --shadow:   none; /* never elevate */

  /* layout */
  --maxw: 1060px;
  --pad:  clamp(20px, 5vw, 40px);

  /* control sizing */
  --control-h:    46px;
  --control-h-sm: 38px;
  --control-h-lg: 54px;

  /* motion */
  --ease:     cubic-bezier(.22, 1, .36, 1); /* @kind other */
  --dur-fast: 0.15s; /* @kind other */
  --dur:      0.24s; /* @kind other */

  /* the signature faint blueprint grid (background) */
  --grid-row: 96px;
  --grid-col: 24px;
}

/* zipka · motion.
   The brand's movement layer: short, meaningful, in character — техника + творчество.
   Restrained Swiss motion — fades and short slides, 1px lift on hover, NO bounce on
   content. Easing is always --ease (cubic-bezier(.22,1,.36,1)); durations sit in the
   150–400ms band. Two tiers ship here:
     1. TOKENS + KEYFRAMES — the raw vocabulary (reusable @keyframes mo-*).
     2. UTILITY CLASSES (.mo-*) — drop-on entrance / state / idle helpers.
   The timing tokens --ease / --dur-fast / --dur live in spacing.css; this file adds
   the longer durations and the keyframe + utility library on top of them.
   prefers-reduced-motion is honoured at the bottom: everything collapses to a fade. */

:root {
  /* longer durations on top of --dur-fast (.15s) / --dur (.24s) from spacing.css */
  --dur-slow:  0.40s; /* @kind other */
  /* section / element entrances */
  --dur-enter: 0.52s; /* @kind other */

  /* loop tempos */
  --dur-spin:    0.9s; /* @kind other */
  --dur-shimmer: 1.4s; /* @kind other */
  --dur-breathe: 4s;   /* @kind other */
}

/* ============================================================= *
 *  KEYFRAMES — the reusable motion vocabulary                   *
 *  (component- and demo-specific loops live with their demos)   *
 * ============================================================= */

/* — entrances (one-shot) — */
@keyframes mo-rise    { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes mo-rise-lg { from { opacity: 0; transform: translateY(34px); } to { opacity: 1; transform: none; } }
@keyframes mo-fade    { from { opacity: 0; } to { opacity: 1; } }
@keyframes mo-pop     { from { opacity: 0; transform: scale(.9); } to { opacity: 1; transform: scale(1); } }

/* — progress / drawing — */
@keyframes mo-draw { to { stroke-dashoffset: 0; } }            /* set stroke-dasharray + dashoffset = path length */
@keyframes mo-bar  { from { transform: scaleX(0); } to { transform: scaleX(1); } } /* transform-origin: left */

/* — feedback — */
@keyframes mo-shake { 0%,100% { transform: translateX(0); } 18% { transform: translateX(-8px); } 38% { transform: translateX(7px); } 58% { transform: translateX(-5px); } 78% { transform: translateX(3px); } }
@keyframes mo-toast { 0% { transform: translateX(115%); opacity: 0; } 12%,78% { transform: translateX(0); opacity: 1; } 100% { transform: translateX(115%); opacity: 0; } }

/* — loading / idle (looping) — */
@keyframes mo-spin    { to { transform: rotate(360deg); } }
@keyframes mo-shimmer { 0% { background-position: -180px 0; } 100% { background-position: 260px 0; } }
@keyframes mo-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes mo-breathe { 0%,100% { transform: translateY(0) scale(1); } 50% { transform: translateY(-5px) scale(1.012); } }
@keyframes mo-blink   { 0%,90%,100% { transform: scaleY(1); } 95% { transform: scaleY(.08); } }

/* — typing (caret + width reveal; pair with steps()/--n) — */
@keyframes mo-type  { from { width: 0; } to { width: var(--n, 100%); } }
@keyframes mo-caret { 0%,100% { border-color: transparent; } 50% { border-color: var(--accent); } }

/* — surface / blueprint — */
@keyframes mo-gridin { from { opacity: 0; } to { opacity: .5; } }

/* ============================================================= *
 *  UTILITY CLASSES — drop-on motion                             *
 *  Apply alongside your markup; all use --ease.                 *
 * ============================================================= */

/* entrances — sit on the visible end-state, animate FROM hidden, so print /
   reduced-motion show content. Gate scroll-reveals by toggling .mo-in yourself,
   or use as-is for above-the-fold elements. */
.mo-rise    { animation: mo-rise    var(--dur-enter) var(--ease) both; }
.mo-rise-lg { animation: mo-rise-lg var(--dur-enter) var(--ease) both; }
.mo-fade    { animation: mo-fade    var(--dur)       var(--ease) both; }
.mo-pop     { animation: mo-pop     var(--dur)       var(--ease) both; }

/* progress / drawing */
.mo-bar  { transform-origin: left center; animation: mo-bar var(--dur-slow) var(--ease) both; }
.mo-draw { animation: mo-draw var(--dur-enter) var(--ease) both; }

/* feedback */
.mo-shake { animation: mo-shake .42s var(--ease); }

/* loading / idle */
.mo-spin    { animation: mo-spin var(--dur-spin) linear infinite; }
.mo-breathe { animation: mo-breathe var(--dur-breathe) ease-in-out infinite; }
.mo-blink   { animation: mo-blink 4.5s var(--ease) infinite; }

/* skeleton shimmer — put on a placeholder block */
.mo-shimmer {
  background: linear-gradient(90deg, var(--surface-2) 0%, var(--line) 40%, var(--surface-2) 80%);
  background-size: 280px 100%;
  background-repeat: no-repeat;
  animation: mo-shimmer var(--dur-shimmer) linear infinite;
}

/* hover affordances — the house 1px lift; press settles back to 0 */
.mo-lift { transition: transform var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease); }
.mo-lift:hover  { transform: translateY(-1px); }
.mo-lift:active { transform: translateY(0); }

/* stagger — set on a parent; children animate in sequence (up to 8) */
.mo-stagger > *               { animation-delay: 0ms; }
.mo-stagger > *:nth-child(2)  { animation-delay: 60ms; }
.mo-stagger > *:nth-child(3)  { animation-delay: 120ms; }
.mo-stagger > *:nth-child(4)  { animation-delay: 180ms; }
.mo-stagger > *:nth-child(5)  { animation-delay: 240ms; }
.mo-stagger > *:nth-child(6)  { animation-delay: 300ms; }
.mo-stagger > *:nth-child(7)  { animation-delay: 360ms; }
.mo-stagger > *:nth-child(8)  { animation-delay: 420ms; }

/* infinite scroller — duplicate the track contents and translate -50% */
.mo-marquee { animation: mo-marquee 18s linear infinite; }

/* ============================================================= *
 *  MASCOT — Зип expressions                                     *
 *  One-shot character beats. Trigger by (re)applying the class. *
 *  Hang them on the mascot wrapper; --ease keeps them in voice. *
 * ============================================================= */
@keyframes mo-hop   { 0% { transform: translateY(0); } 12% { transform: translateY(-22px); } 24% { transform: translateY(0); } 33% { transform: translateY(-9px); } 42%,100% { transform: translateY(0); } }
@keyframes mo-nod   { 0% { transform: translateY(0) rotate(0); } 12% { transform: translateY(7px) rotate(4deg); } 26% { transform: translateY(0) rotate(0); } 38% { transform: translateY(6px) rotate(3deg); } 50%,100% { transform: translateY(0) rotate(0); } }
@keyframes mo-no    { 0% { transform: rotate(0); } 9% { transform: rotate(-7deg); } 21% { transform: rotate(6deg); } 33% { transform: rotate(-4deg); } 45% { transform: rotate(2deg); } 54%,100% { transform: rotate(0); } }
@keyframes mo-tilt  { 0%,100% { transform: rotate(0); } 50% { transform: rotate(-8deg); } }
@keyframes mo-sway  { 0%,100% { transform: rotate(-3deg); } 50% { transform: rotate(3deg); } }
@keyframes mo-sink  { 0% { transform: translateY(0) rotate(0); } 100% { transform: translateY(8px) rotate(4deg); } }
@keyframes mo-jelly { 0% { transform: scale(1,1); } 10% { transform: scale(1.12,.86); } 22% { transform: scale(.9,1.1); } 33% { transform: scale(1.03,.97); } 42%,100% { transform: scale(1,1); } }
@keyframes mo-wink  { 0%,38%,100% { transform: scaleY(1); } 48%,62% { transform: scaleY(.12); } }
@keyframes mo-flip  { 0% { transform: scaleX(1); } 46% { transform: scaleX(.05); } 54% { transform: scaleX(-.05); } 100% { transform: scaleX(-1); } }
@keyframes mo-turn  { 0% { transform: rotateY(0); } 100% { transform: rotateY(360deg); } }
@keyframes mo-wave  { 0%,100% { transform: rotate(0); } 25% { transform: rotate(-44deg); } 50% { transform: rotate(-16deg); } 75% { transform: rotate(-44deg); } }
@keyframes mo-peek  { 0% { opacity: 0; transform: translateX(-110px) rotate(-12deg); } 16% { opacity: 1; transform: translateX(10px) rotate(4deg); } 28%,76% { opacity: 1; transform: translateX(0) rotate(0); } 92%,100% { opacity: 0; transform: translateX(-110px) rotate(-12deg); } }
@keyframes mo-zzz   { 0% { opacity: 0; transform: translate(0,0) scale(.5); } 25% { opacity: 1; } 100% { opacity: 0; transform: translate(16px,-32px) scale(1.15); } }
@keyframes mo-qmark { 0%,100% { opacity: 0; transform: translateY(5px) scale(.7); } 40%,70% { opacity: 1; transform: translateY(0) scale(1); } }

/* mascot utility classes — one-shot beats + the idle loops */
.mo-hop   { animation: mo-hop   1.1s var(--ease) both; }
.mo-nod   { animation: mo-nod   1.1s var(--ease) both; }
.mo-no    { animation: mo-no    1.0s var(--ease) both; }
.mo-jelly { animation: mo-jelly .8s  var(--ease) both; }
.mo-wink  { animation: mo-wink  1.2s var(--ease) both; }
.mo-tilt  { animation: mo-tilt  2.4s ease-in-out infinite; }   /* idle */
.mo-sway  { animation: mo-sway  3.6s ease-in-out infinite; }   /* idle */

/* ============================================================= *
 *  EXPRESSIVE — energy, celebration, the tech↔art spark         *
 *  Used sparingly: success moments, the молния/bolt brand beat. *
 * ============================================================= */
@keyframes mo-spark   { 0% { opacity: 0; transform: scale(0) rotate(0); } 45% { opacity: 1; transform: scale(1) rotate(40deg); } 100% { opacity: 0; transform: scale(1.5) rotate(80deg); } }
@keyframes mo-bolt    { 0% { opacity: 0; transform: scale(.3); } 60% { opacity: 1; transform: scale(1.14); } 100% { opacity: 1; transform: scale(1); } }
@keyframes mo-boltglow{ 0%,100% { stroke-width: 5; opacity: .5; } 50% { stroke-width: 7.5; opacity: 1; } }
@keyframes mo-zap     { 0% { opacity: 0; transform: scale(.4) rotate(-12deg); } 40% { opacity: 1; transform: scale(1.12) rotate(6deg); } 100% { opacity: 0; transform: scale(.8) rotate(12deg); } }
@keyframes mo-confetti{ 0% { opacity: 0; transform: translate(0,0) scale(0) rotate(0); } 6% { opacity: 1; } 38%,100% { opacity: 0; transform: translate(var(--cx,0),var(--cy,-40px)) scale(1) rotate(var(--cr,90deg)); } }
@keyframes mo-loopbar { 0% { transform: scaleX(0); } 65% { transform: scaleX(1); } 100% { transform: scaleX(1); opacity: .25; } }

/* ============================================================= *
 *  COMPONENT STATE — paired enter/idle keyframes for UI parts   *
 *  These encode a component's transition (menu open, switch on, *
 *  modal in, accordion expand, chip select, copy confirm…).     *
 *  The ping-pong (…→hold→back) variants are tuned for looping    *
 *  spec demos; for production use the in/out halves directly.   *
 * ============================================================= */
/* burger → close */
@keyframes mo-bt   { 0%,7% { transform: translateY(0) rotate(0); } 20%,72% { transform: translateY(6px) rotate(45deg); } 85%,100% { transform: translateY(0) rotate(0); } }
@keyframes mo-bm   { 0%,7% { opacity: 1; } 20%,72% { opacity: 0; } 85%,100% { opacity: 1; } }
@keyframes mo-bb   { 0%,7% { transform: translateY(0) rotate(0); } 20%,72% { transform: translateY(-6px) rotate(-45deg); } 85%,100% { transform: translateY(0) rotate(0); } }
@keyframes mo-menu { 0%,7% { transform: translateY(-12px); opacity: 0; } 20%,72% { transform: translateY(0); opacity: 1; } 85%,100% { transform: translateY(-12px); opacity: 0; } }
/* course card lift + arrow nudge */
@keyframes mo-cardlift  { 0%,14% { transform: translateY(0); border-color: var(--line-2); } 34%,76% { transform: translateY(-3px); border-color: var(--text); } 92%,100% { transform: translateY(0); border-color: var(--line-2); } }
@keyframes mo-cardarrow { 0%,14% { transform: translateX(0); } 34%,76% { transform: translateX(6px); } 92%,100% { transform: translateX(0); } }
/* switch track + knob */
@keyframes mo-track { 0%,12% { background: var(--line-2); } 32%,70% { background: var(--accent); } 88%,100% { background: var(--line-2); } }
@keyframes mo-knob  { 0%,12% { transform: translateX(0); } 32%,70% { transform: translateX(20px); } 88%,100% { transform: translateX(0); } }
/* dialog scrim + panel */
@keyframes mo-scrim { 0%,6% { opacity: 0; } 18%,80% { opacity: 1; } 92%,100% { opacity: 0; } }
@keyframes mo-modal { 0%,8% { opacity: 0; transform: translateY(22px); } 24%,80% { opacity: 1; transform: translateY(0); } 92%,100% { opacity: 0; transform: translateY(22px); } }
/* accordion body + plus→cross */
@keyframes mo-accbody { 0%,12% { max-height: 0; opacity: 0; } 32%,74% { max-height: 90px; opacity: 1; } 90%,100% { max-height: 0; opacity: 0; } }
@keyframes mo-accplus { 0%,12% { transform: rotate(0); } 32%,74% { transform: rotate(45deg); } 90%,100% { transform: rotate(0); } }
/* chip select */
@keyframes mo-chip { 0%,15% { background: transparent; color: var(--text); border-color: var(--line-2); } 35%,78% { background: var(--accent); color: #fff; border-color: var(--accent); } 92%,100% { background: transparent; color: var(--text); border-color: var(--line-2); } }
/* copy → confirmed */
@keyframes mo-copybg { 0%,16% { background: transparent; } 36%,80% { background: var(--success); } 92%,100% { background: transparent; } }
@keyframes mo-copyA  { 0%,16% { opacity: 1; } 30%,86% { opacity: 0; } 96%,100% { opacity: 1; } }
@keyframes mo-copyB  { 0%,16% { opacity: 0; } 30%,86% { opacity: 1; } 96%,100% { opacity: 0; } }
/* link underline grow */
@keyframes mo-underline { 0%,15% { background-size: 0% 2px; } 35%,75% { background-size: 100% 2px; } 92%,100% { background-size: 0% 2px; } }
/* button press squish */
@keyframes mo-shrink { 0%,18% { padding-top: 22px; padding-bottom: 22px; } 55%,100% { padding-top: 9px; padding-bottom: 9px; } }

/* ============================================================= *
 *  REDUCED MOTION — collapse everything to a quiet fade         *
 * ============================================================= */
@media (prefers-reduced-motion: reduce) {
  .mo-rise, .mo-rise-lg, .mo-pop, .mo-bar, .mo-draw {
    animation: mo-fade var(--dur) var(--ease) both;
  }
  .mo-shake, .mo-spin, .mo-breathe, .mo-blink, .mo-shimmer, .mo-marquee,
  .mo-hop, .mo-nod, .mo-no, .mo-jelly, .mo-wink, .mo-tilt, .mo-sway { animation: none; }
  .mo-lift:hover, .mo-lift:active { transform: none; }
}

/* zipka · patterns & illustration textures.
   Two jobs:
   1) Surface PATTERNS — thin, "notebook-quiet" motifs for backgrounds, slides,
      packaging, dividers. Drop a .zip-pat-* class on any surface.
   2) Illustration TEXTURE controls — the variables the house illustration style
      relies on (line weight, halftone pitch, accent-coloured dots, grain).
   Everything ties to existing brand tokens — no new hues are introduced here.
   Tune any pattern in place by overriding the --pat-* / --halftone-* vars. */

:root {
  /* ---- shared pattern controls ---- */
  --pat-cell:    24px;   /* repeat size — matches the blueprint grid column */
  --pat-stroke:  1px;    /* hairline weight — "almost a whisper" */
  --pat-dot:     1.3px;  /* dot radius for the dot grid */
  --pat-fade:    14%;    /* presence: how far the mark mixes toward transparent */

  /* derived faint mark colour (quiet by default; raise --pat-fade to strengthen) */
  --pat-line: color-mix(in srgb, var(--text) var(--pat-fade), transparent);
  /* an accent-tinted variant for hero / brand moments */
  --pat-accent: color-mix(in srgb, var(--accent) 22%, transparent);

  /* ---- illustration texture controls ---- */
  --ink-stroke:    2.4px;          /* default illustration line weight at 1x */
  --halftone-cell: 6px;            /* dot pitch in halftone fills */
  --halftone-dot:  1.6px;          /* dot radius in halftone fills */
  --halftone-ink:  var(--accent);  /* coloured halftone uses the live accent */
}

/* ============================================================= *
 *  SURFACE PATTERNS                                             *
 * ============================================================= */

/* — dot grid · the PRIMARY zipka pattern (quiet, notebook-like) — */
.zip-pat-dots {
  background-color: var(--bg);
  background-image: radial-gradient(var(--pat-line) var(--pat-dot), transparent calc(var(--pat-dot) + 0.6px));
  background-size: var(--pat-cell) var(--pat-cell);
}

/* — клетка · notebook square grid — */
.zip-pat-grid {
  background-color: var(--bg);
  background-image:
    linear-gradient(var(--pat-line) var(--pat-stroke), transparent var(--pat-stroke)),
    linear-gradient(90deg, var(--pat-line) var(--pat-stroke), transparent var(--pat-stroke));
  background-size: var(--pat-cell) var(--pat-cell);
}

/* — diagonal hairline hatch — */
.zip-pat-hatch {
  background-color: var(--bg);
  background-image: repeating-linear-gradient(45deg, var(--pat-line) 0 var(--pat-stroke), transparent var(--pat-stroke) var(--pat-cell));
}

/* — zip band · the brand motif (молния): a centre rule with repeating teeth — */
.zip-pat-zip {
  --zip-w: 16px;       /* width of the toothed band */
  --zip-pitch: 9px;    /* tooth spacing */
  background-color: var(--bg);
  background-image:
    linear-gradient(90deg, transparent calc(50% - 0.5px), var(--pat-line) calc(50% - 0.5px), var(--pat-line) calc(50% + 0.5px), transparent calc(50% + 0.5px)),
    repeating-linear-gradient(0deg, var(--pat-line) 0 1.6px, transparent 1.6px var(--zip-pitch));
  background-size: 100% 100%, var(--zip-w) var(--zip-pitch);
  background-position: center, center top;
  background-repeat: no-repeat, repeat-y;
}

/* accent-tinted modifier — swaps the quiet ink mark for a faint accent tint */
.zip-pat-accent { --pat-line: var(--pat-accent); }
/* stronger presence modifier */
.zip-pat-bold   { --pat-fade: 26%; }

/* ============================================================= *
 *  ILLUSTRATION HALFTONE FILL (for HTML blocks / shapes)        *
 *  For SVG line-art, use the <pattern>/filter defs shipped in   *
 *  assets/illustration-filters.svg instead.                     *
 * ============================================================= */

/* coloured halftone (the house default) — accent dots on paper */
.zip-halftone {
  background-color: var(--bg);
  background-image: radial-gradient(var(--halftone-ink) var(--halftone-dot), transparent calc(var(--halftone-dot) + 0.6px));
  background-size: var(--halftone-cell) var(--halftone-cell);
}
/* neutral halftone — ink dots, for monochrome work */
.zip-halftone-ink { --halftone-ink: var(--text); }

/* zipka · base — minimal global defaults applied wherever styles.css is linked.
   Tokens carry the system; this just wires sensible document defaults and the
   signature faint "blueprint" grid so specimens and pages look on-brand. */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--lh-body);
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }

/* sharp corners + no elevation, enforced as a safety net */
input, select, textarea, button { border-radius: var(--radius); font-family: inherit; }

/* the faint blueprint grid — drop on any full-bleed surface */
.zip-grid {
  background-image:
    linear-gradient(var(--line) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--line) 35%, transparent) 1px, transparent 1px);
  background-size: 100% var(--grid-row), var(--grid-col) 100%;
}

/* eyebrow — the bracketed lowercase label, brand signature */
.zip-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
  color: var(--text-muted);
  text-transform: lowercase;
}

/* zipka app — адаптивный веб-кабинет и мобильный PWA. Дизайн портирован из Claude Design прототипа
   (zipka PWA.dc.html): Swiss/brutalist, монопара JetBrains Mono + Hanken Grotesk,
   DS-палитра, акцент Klein, sharp corners (radius:0), depth = hairlines, не тень.
   Большая часть стилей экранов живёт inline в разметке (app.js) на DS-токенах —
   как в исходном прототипе. Тут: токены DS, адаптивная оболочка, zk-компоненты
   (Button/Badge), keyframes переходов и утилиты. */

/* Полный эталон дизайн-системы zipka — единственный источник токенов:
   palette + semantic (light/dark + accent-варианты), typography, spacing,
   motion (все @keyframes/.mo-*), patterns, fonts, base. */


:root{
  --font-mono: var(--font-mono, 'JetBrains Mono', monospace);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
  --tab-h: 64px;
}

*{ box-sizing:border-box; margin:0; padding:0; -webkit-tap-highlight-color:transparent; }
html,body{ height:100%; }
html{ -webkit-text-size-adjust:100%; }
body{
  font-family:var(--font-sans); color:var(--text);
  background:var(--bg);
  -webkit-font-smoothing:antialiased; line-height:1.5;
  overscroll-behavior-y:none; user-select:none;
  min-height:100dvh; overflow:hidden;
}
img{ max-width:100%; display:block; }
button{ font-family:inherit; cursor:pointer; border:0; background:none; color:inherit; }
input{ font-family:inherit; }
[data-act]:focus-visible, input:focus-visible{
  outline:3px solid color-mix(in srgb,var(--accent) 45%,transparent);
  outline-offset:2px;
}

/* ===== адаптивная оболочка приложения ===== */
#phone{
  position:relative; width:100%; height:100dvh;
  background:var(--bg); overflow:hidden;
}

/* безопасная зона сверху (вырез / статус-бар системы) */
.safe-top{ height:max(var(--safe-t), 12px); flex:none; }

/* экран и скролл */
.screen{ position:absolute; inset:0 0 0 240px; display:flex; flex-direction:column; }
.zk-scroll{ flex:1; overflow-y:auto; -webkit-overflow-scrolling:touch; }
.zk-scroll::-webkit-scrollbar{ width:0; height:0; }
.screen{ animation:scr-in .26s var(--ease) both; }
@keyframes scr-in{ from{ opacity:0; transform:translateY(6px); } to{ opacity:1; transform:none; } }

/* ===== единый каркас кабинета ===== */
.app-page{ width:100%; max-width:1280px; margin:0 auto; padding:var(--space-7) clamp(28px,4vw,64px) var(--space-8); }
.home-stack{ display:grid; gap:var(--space-4); max-width:980px; margin:0 auto; }
.app-header{ display:flex; align-items:center; gap:var(--space-3); padding-bottom:var(--space-4); border-bottom:1px solid var(--line); }
.app-header h1,.page-heading h1{ margin:2px 0 0; font-family:var(--font-sans); font-size:var(--text-h3); line-height:1.2; letter-spacing:-.02em; }
.app-kicker,.section-label{ font-family:var(--font-mono); font-size:var(--text-xs); color:var(--text-muted); letter-spacing:.02em; }
.mascot-button{ width:46px; height:46px; padding:0; border:0; background:transparent; cursor:pointer; flex:none; }
.mascot-static{ width:48px; height:48px; flex:none; }

.lesson-hero,.continue-card,.parent-summary,.payment-card,.profile-card{ border:1px solid var(--line); background:var(--surface); padding:var(--space-5); }
.lesson-hero{ border-color:var(--line-strong); box-shadow:inset 0 4px 0 var(--accent); padding-top:var(--space-6); }
.lesson-hero__head,.continue-card__row,.parent-summary__person{ display:flex; align-items:center; gap:var(--space-3); }
.lesson-hero__head{ margin-top:var(--space-3); }
.lesson-hero h2,.continue-card h2,.parent-summary h2,.payment-card h2,.profile-card h2,.sheet-panel h2,.welcome-card h2{ margin:0; font-family:var(--font-sans); font-size:18px; line-height:1.25; letter-spacing:-.015em; }
.lesson-hero__head p,.continue-card p,.parent-summary p,.payment-card p,.profile-card p{ margin:3px 0 0; color:var(--text-muted); font-size:var(--text-sm); }
.lesson-icon{ width:48px; height:48px; display:grid; place-items:center; flex:none; color:var(--accent); background:var(--accent-tint); border:1px solid var(--accent-line); font-size:24px; }
.lesson-hero__goal{ margin:var(--space-4) 0; max-width:52ch; color:var(--text-soft); font-size:var(--text-sm); line-height:1.55; }
.lesson-hero__teacher{ display:flex; justify-content:space-between; gap:var(--space-3); margin-bottom:var(--space-4); padding:var(--space-3) 0; border-top:1px solid var(--line); border-bottom:1px solid var(--line); font-size:var(--text-sm); }
.lesson-hero__teacher span{ color:var(--text-muted); }
.action-pair{ display:flex; gap:var(--space-2); flex-wrap:wrap; }
.action-pair .zk-btn{ flex:1 1 210px; }
.lesson-hero.compact .lesson-hero__head{ margin-bottom:var(--space-4); }

.continue-card__row{ margin:var(--space-3) 0 var(--space-4); }
.continue-card__row>div:nth-child(2){ flex:1; min-width:0; }
.progress-summary{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); border:1px solid var(--line); background:var(--surface); }
.progress-summary__item{ padding:var(--space-4); min-width:0; }
.progress-summary__item+ .progress-summary__item{ border-left:1px solid var(--line); }
.progress-summary__item span,.progress-summary__item small{ display:block; color:var(--text-muted); font-family:var(--font-mono); font-size:11px; }
.progress-summary__item strong{ display:block; margin:5px 0 2px; font-family:var(--font-mono); font-size:24px; font-weight:500; color:var(--text); }
.lesson-balance-note{ display:flex; align-items:center; justify-content:space-between; gap:var(--space-3); padding:var(--space-3) 0; color:var(--text-muted); font-size:var(--text-xs); }
.lesson-balance-note strong{ color:var(--text); }
.lesson-balance-note button{ color:var(--accent); font-family:var(--font-mono); font-size:var(--text-xs); text-decoration:underline; text-underline-offset:3px; }
.idea-launch{ display:flex; align-items:center; gap:var(--space-3); padding:var(--space-4); border:1px solid var(--line); background:var(--surface); color:var(--text); text-decoration:none; transition:border-color var(--dur-fast,.15s),transform var(--dur-fast,.15s); }
.idea-launch>span{ flex:1; min-width:0; }
.idea-launch strong,.idea-launch small{ display:block; }
.idea-launch strong{ font-family:var(--font-sans); font-size:var(--text-sm); font-weight:600; }
.idea-launch small{ margin-top:3px; color:var(--text-muted); font-size:var(--text-xs); line-height:1.45; }
.idea-launch>b{ color:var(--accent); font-family:var(--font-mono); font-size:20px; font-weight:400; }
@media(hover:hover){.idea-launch:hover{ border-color:var(--accent); transform:translateY(-1px); }}

/* ===== кабинет преподавателя ===== */
.teacher-dashboard{ width:100%; }
.teacher-header{ display:flex; align-items:flex-end; justify-content:space-between; gap:var(--space-4); margin-bottom:var(--space-6); padding-bottom:var(--space-5); border-bottom:1px solid var(--line); }
.teacher-header h1{ margin:3px 0 0; font-family:var(--font-sans); font-size:clamp(26px,3vw,38px); line-height:1.1; letter-spacing:-.035em; }
.teacher-role{ padding:6px 10px; border:1px solid var(--accent-line); color:var(--accent); font-family:var(--font-mono); font-size:11px; }
.teacher-grid{ display:grid; grid-template-columns:minmax(0,1.45fr) minmax(320px,.8fr); gap:var(--space-5); align-items:start; }
.teacher-lessons-panel,.teacher-next-panel{ border:1px solid var(--line-strong); background:var(--surface); }
.teacher-lessons-panel{ min-height:560px; display:flex; flex-direction:column; }
.teacher-panel-head{ display:flex; align-items:center; justify-content:space-between; gap:var(--space-4); padding:var(--space-5); border-bottom:1px solid var(--line); }
.teacher-panel-head h2,.teacher-next-panel h2{ margin:5px 0 0; font-size:22px; line-height:1.2; }
.teacher-lesson-list{ flex:1; }
.teacher-lesson-row{ width:100%; min-height:88px; display:grid; grid-template-columns:70px minmax(0,1fr) auto 16px; align-items:center; gap:var(--space-4); padding:var(--space-4) var(--space-5); border-bottom:1px solid var(--line); text-align:left; }
.teacher-lesson-row:hover{ background:var(--surface-2); }
.teacher-lesson-row time{ color:var(--accent); font-family:var(--font-mono); font-size:15px; }
.teacher-lesson-row span,.teacher-lesson-row b,.teacher-lesson-row small{ display:block; }
.teacher-lesson-row b{ font-size:15px; }
.teacher-lesson-row small{ margin-top:4px; color:var(--text-muted); font-family:var(--font-mono); font-size:11px; }
.teacher-lesson-row em{ padding:4px 7px; border:1px solid var(--success); color:var(--success); font-family:var(--font-mono); font-size:10px; font-style:normal; white-space:nowrap; }
.teacher-lesson-row:nth-child(n+2) em{ border-color:var(--accent-line); color:var(--accent); }
.teacher-lesson-row i{ color:var(--text-muted); font-size:18px; font-style:normal; }
.teacher-schedule-link{ display:block; margin-top:auto; padding:var(--space-4) var(--space-5); color:var(--accent); font-family:var(--font-mono); font-size:12px; text-decoration:none; }
.teacher-next-panel{ padding:var(--space-5); }
.teacher-next-time{ margin-top:var(--space-5); color:var(--accent); font-family:var(--font-mono); font-size:18px; }
.teacher-next-panel dl{ margin:var(--space-5) 0; border-top:1px solid var(--line); border-bottom:1px solid var(--line); }
.teacher-next-panel dl div{ display:flex; justify-content:space-between; gap:var(--space-3); padding:11px 0; }
.teacher-next-panel dl div+div{ border-top:1px solid var(--line); }
.teacher-next-panel dt{ color:var(--text-muted); font-size:13px; }
.teacher-next-panel dd{ text-align:right; font-family:var(--font-mono); font-size:12px; }
.teacher-next-panel dd.is-ready{ color:var(--success); }
.teacher-next-panel>.idea-launch{ margin-top:var(--space-3); }
.parent-summary__person{ margin-bottom:var(--space-4); }
.parent-summary__person>div:last-child{ min-width:0; }
.payment-card{ display:flex; align-items:center; justify-content:space-between; gap:var(--space-4); }
.payment-card>div{ min-width:0; }
.payment-card p{ max-width:42ch; }

.page-heading{ width:100%; max-width:none; margin:0 0 var(--space-4); text-align:left; }
.profile-card,.role-switch,.settings-list,.theme-row,.profile-help,.demo-note,.profile-section-label{ max-width:660px; margin-left:auto; margin-right:auto; }
.profile-card{ display:flex; align-items:center; gap:var(--space-4); border-color:var(--line-strong); }
.profile-section-label{ margin-top:var(--space-6); margin-bottom:var(--space-2); }
.role-switch{ display:flex; gap:var(--space-2); }
.profile-payment{ max-width:660px; margin:var(--space-4) auto 0; }
.settings-list{ border:1px solid var(--line); background:var(--surface); }
.settings-row,.theme-row{ width:100%; min-height:52px; display:flex; align-items:center; gap:var(--space-3); padding:0 var(--space-4); border-bottom:1px solid var(--line); color:var(--text); text-align:left; cursor:pointer; }
.settings-row:last-child{ border-bottom:0; }
.settings-row>span:first-child,.theme-row>span:last-child{ color:var(--accent); font-size:20px; }
.settings-row strong{ flex:1; font-family:var(--font-sans); font-size:var(--text-sm); font-weight:500; }
.settings-row small{ color:var(--text-muted); font-family:var(--font-mono); }
.theme-row{ justify-content:space-between; border:1px solid var(--line); background:var(--surface); font-family:var(--font-sans); font-size:var(--text-sm); }
.profile-help{ margin-top:var(--space-5); }
.demo-note{ margin-top:var(--space-5); color:var(--text-muted); font-family:var(--font-mono); font-size:11px; text-align:center; }

.push-layer{ position:absolute; inset:0 0 0 240px; z-index:50; display:flex; flex-direction:column; background:var(--bg); isolation:isolate; animation:zk-push .3s var(--ease); }
.push-layer>.zk-scroll{ width:min(760px,calc(100% - 48px)); margin:0 auto; }
.chat-layer{ z-index:55; }
.sheet-scrim,.welcome-scrim{ position:absolute; inset:0; background:rgba(12,12,14,.72); animation:zk-scrim .2s var(--ease); }
.sheet-scrim{ z-index:60; }
.sheet-panel{ position:absolute; left:0; right:0; bottom:0; z-index:61; max-height:88%; overflow:auto; padding:var(--space-3) var(--space-6) calc(var(--space-7) + var(--safe-b)); border-top:1px solid var(--line-strong); background:var(--surface); animation:zk-sheet .3s var(--ease); }
.sheet-panel>p{ margin:var(--space-2) 0 0; max-width:55ch; color:var(--text-muted); font-size:var(--text-sm); line-height:1.5; }
.sheet-handle{ width:40px; height:3px; margin:0 auto var(--space-5); background:var(--line-2); }
.sheet-close{ position:absolute; top:var(--space-3); right:var(--space-4); width:40px; height:40px; display:grid; place-items:center; border:1px solid var(--line); background:var(--surface); color:var(--text); cursor:pointer; }
.pack-list{ display:grid; gap:var(--space-2); margin-top:var(--space-4); }
.pack-option{ width:100%; min-height:64px; display:flex; align-items:center; justify-content:space-between; gap:var(--space-4); padding:var(--space-3) var(--space-4); border:1px solid var(--line); background:var(--surface); color:var(--text); text-align:left; cursor:pointer; }
.pack-option span,.pack-option small{ display:block; }
.pack-option strong{ font-family:var(--font-sans); font-size:var(--text-sm); }
.pack-option small{ margin-top:3px; color:var(--text-muted); font-family:var(--font-mono); font-size:11px; }
.pack-option>b{ white-space:nowrap; font-family:var(--font-mono); font-size:var(--text-sm); }
.payment-note{ font-size:11px!important; }

.welcome-scrim{ z-index:89; }
.welcome-card{ position:absolute; left:50%; top:50%; z-index:90; width:min(520px,calc(100% - 32px)); transform:translate(-50%,-50%); padding:var(--space-6); border:1px solid var(--line-strong); background:var(--surface); box-shadow:0 24px 70px rgba(0,0,0,.32); }
.welcome-card__brand{ display:flex; align-items:center; gap:var(--space-2); margin-bottom:var(--space-4); font-family:var(--font-mono); font-weight:600; }
.welcome-card>p{ margin:var(--space-2) 0 var(--space-5); color:var(--text-muted); font-size:var(--text-sm); }
.welcome-list{ display:grid; gap:var(--space-2); margin:0 0 var(--space-5); padding:0; list-style:none; }
.welcome-list li{ display:flex; align-items:center; gap:var(--space-3); padding:var(--space-3); background:var(--surface-2); }
.welcome-list li>.zk-icon{ flex:none; color:var(--accent); font-size:22px; }
.welcome-list span,.welcome-list strong,.welcome-list small{ display:block; }
.welcome-list strong{ font-family:var(--font-sans); font-size:var(--text-sm); }
.welcome-list small{ margin-top:2px; color:var(--text-muted); font-size:var(--text-xs); }

@media(max-width:620px){
  .app-page{ padding:var(--space-4) var(--space-4) var(--space-7); }
  .action-pair{ flex-direction:column; }
  .action-pair .zk-btn{ flex:auto; width:100%; }
  .continue-card__row{ align-items:flex-start; flex-wrap:wrap; }
  .continue-card__row .zk-badge{ margin-left:54px; }
  .payment-card{ align-items:flex-start; flex-direction:column; }
  .payment-card .zk-btn{ width:100%; }
  .role-switch{ flex-direction:column; }
  .welcome-card{ padding:var(--space-5); }
}

/* секционный заголовок-«ребро» */
.h-sub{
  font-family:var(--font-mono); font-size:11px; letter-spacing:.06em;
  color:var(--text-muted); text-transform:lowercase;
  margin:22px 0 10px; padding-top:12px; border-top:1px solid var(--line);
}

/* ===== навигация: боковая на компьютере ===== */
.tabbar{
  position:absolute; inset:0 auto 0 0; width:240px; z-index:60; display:flex; flex-direction:column;
  background:var(--surface); border-right:1px solid var(--line);
}
.sidebar-brand{ height:82px; display:flex; align-items:center; padding:0 26px; border-bottom:1px solid var(--line); color:var(--accent); font-family:var(--font-mono); font-size:24px; font-weight:700; letter-spacing:.04em; }
.sidebar-links{ display:flex; flex-direction:column; gap:4px; padding:24px 14px; }
.tabbar :is(button,.nav-link){
  min-height:48px; display:flex; align-items:center; gap:13px; padding:0 14px;
  font-family:var(--font-sans); font-size:14px; color:var(--text-muted); text-align:left;
}
.tabbar :is(button,.nav-link) .zk-icon{ font-size:20px; }
.tabbar :is(button,.nav-link).on{ color:var(--accent); background:var(--accent-tint); }
.sidebar-mascot{ width:62px; height:58px; margin:auto 22px 12px; }
.sidebar-mascot img{ width:100%; height:100%; object-fit:contain; }
.sidebar-account{ margin:0 18px 22px; padding-top:16px; border-top:1px solid var(--line); }
.sidebar-account strong,.sidebar-account span{ display:block; }
.sidebar-account strong{ font-size:14px; }
.sidebar-account span{ margin-top:2px; color:var(--text-muted); font-family:var(--font-mono); font-size:11px; }

@media(max-width:820px){
  .screen{ inset:0 0 var(--tab-h) 0; }
  .app-page{ max-width:720px; padding:var(--space-4) var(--space-4) var(--space-7); }
  .home-stack{ max-width:660px; }
  .push-layer{ inset:0; }
  .push-layer>.zk-scroll{ width:100%; }
  .tabbar{ inset:auto 0 0 0; width:auto; height:calc(var(--tab-h) + var(--safe-b)); padding-bottom:var(--safe-b); flex-direction:row; background:color-mix(in srgb,var(--bg) 92%,transparent); backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px); border:0; border-top:1px solid var(--line); }
  .sidebar-brand,.sidebar-account,.sidebar-mascot{ display:none; }
  .sidebar-links{ width:100%; display:flex; flex-direction:row; gap:0; padding:0; }
  .tabbar :is(button,.nav-link){ flex:1; min-height:var(--tab-h); flex-direction:column; align-items:center; justify-content:center; gap:4px; padding:0; font-family:var(--font-mono); font-size:10px; text-align:center; }
  .tabbar :is(button,.nav-link) .zk-icon{ font-size:20px; }
  .teacher-header{ align-items:center; margin-bottom:var(--space-4); padding-bottom:var(--space-4); }
  .teacher-header h1{ font-size:24px; }
  .teacher-grid{ display:flex; flex-direction:column; gap:var(--space-4); }
  .teacher-next-panel{ order:-1; width:100%; }
  .teacher-lessons-panel{ width:100%; min-height:0; }
  .teacher-panel-head{ align-items:stretch; flex-direction:column; }
  .teacher-lesson-row{ grid-template-columns:54px minmax(0,1fr) 16px; gap:var(--space-3); padding:var(--space-3) var(--space-4); }
  .teacher-lesson-row em{ grid-column:2; width:max-content; }
  .teacher-lesson-row i{ grid-column:3; grid-row:1 / span 2; }
}

/* ===== zk-icon ===== */
.zk-icon{
  width:1em; height:1em; display:inline-block; vertical-align:-.14em;
  fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round;
}

/* ===== Button (DS) ===== */
.zk-btn{
  --bh:46px;
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  height:var(--bh); padding:0 18px; border:1px solid transparent;
  font-family:var(--font-mono); font-weight:500; font-size:14px; letter-spacing:-.01em;
  cursor:pointer; white-space:nowrap; transition:background var(--dur-fast,.15s), border-color var(--dur-fast,.15s), transform var(--dur-fast,.15s);
}
.zk-btn.block{ display:flex; width:100%; }
.zk-btn.sm{ --bh:38px; font-size:13px; padding:0 14px; }
.zk-btn.lg{ --bh:54px; font-size:15px; }
.zk-btn.accent{ background:var(--accent); color:var(--accent-contrast); border-color:var(--accent); }
.zk-btn.outline{ background:var(--surface); color:var(--text); border-color:var(--line-strong); }
.zk-btn.ghost{ background:transparent; color:var(--text-muted); border-color:var(--line); }
.zk-btn[disabled]{ opacity:.5; cursor:not-allowed; }
@media(hover:hover){
  .zk-btn.accent:not([disabled]):hover{ background:var(--accent-hover); }
  .zk-btn.outline:not([disabled]):hover{ background:var(--surface-2); }
  .zk-btn:not([disabled]):active{ transform:translateY(1px); }
}

/* ===== Badge (DS) ===== */
.zk-badge{
  display:inline-flex; align-items:center; height:22px; padding:0 8px;
  font-family:var(--font-mono); font-size:11px; font-weight:500; letter-spacing:.01em;
  border:1px solid var(--line); white-space:nowrap;
}
.zk-badge.accent{ color:var(--accent); border-color:var(--accent); }
.zk-badge.accent.soft{ color:var(--accent); border-color:var(--accent-line); background:var(--accent-tint); }
.zk-badge.success{ color:var(--success); border-color:var(--success); }
.zk-badge.success.soft{ color:var(--success); border-color:transparent; background:var(--success-tint); }
.zk-badge.neutral{ color:var(--text-muted); border-color:var(--line); }
.zk-badge.neutral.soft{ color:var(--text-muted); border-color:transparent; background:var(--surface-2); }

/* ===== маскот ===== */
.mascot{ display:inline-flex; }
.mascot.mo-hop{ animation:mo-hop .5s var(--ease); }
.mascot img{ width:100%; height:100%; object-fit:contain; animation:mo-sway 4.5s ease-in-out infinite; transform-origin:center bottom; }

/* всплытие карточек при входе на экран */
.zk-scroll > div > .mo-lift{ transition:transform var(--dur-fast,.15s), border-color var(--dur-fast,.15s); }
@media(hover:hover){ .mo-lift:hover{ transform:translateY(-1px); border-color:var(--line-strong); } }

/* keyframes переходов (push-экраны, шторка, скрим, поп) */
@keyframes zk-push{ from{ transform:translateX(22px); opacity:.6; } to{ transform:none; opacity:1; } }
@keyframes zk-sheet{ from{ transform:translateY(26px); } to{ transform:translateY(0); } }
@keyframes zk-scrim{ from{ opacity:0; } to{ opacity:1; } }
@keyframes zk-pop{ from{ transform:scale(.96); opacity:.4; } to{ transform:none; opacity:1; } }

@media(prefers-reduced-motion:reduce){
  *{ animation:none !important; }
}
