/* СОБРАННЫЙ ФАЙЛ — не правьте его руками.
   Источник: eddy/styles.css, собирается `manage.py build_css`.
   Правьте исходники в static/eddy/, потом пересоберите. */

/* ── eddy/tokens/fonts.css ── */
/* ЭДДИ webfonts.

   Days One — начертание слова «ЭДДИ» в логотипе. Файл предоставлен школой и
   САМОХОСТИТСЯ: assets/fonts/DaysOne-Regular.ttf, лицензия OFL (assets/fonts/DaysOne-OFL.txt).
   ВАЖНО: кириллица в нём ЕСТЬ — проверено на файле (Э, Д, И совпадают с логотипом).
   Поэтому «ЭДДИ» можно набирать шрифтом, а не только ставить картинкой.
   Применение: логотип, крупные акценты, надзаголовки. Абзацы им не набирают —
   очень широкие буквы и один вес.

   Montserrat — наборный текст публичного сайта (предпочтение школы).
   Иероглифы — два начертания, у каждого своя работа:
   · Ma Shan Zheng (马善政) — кисть. Клетка прописей, печати, награды, крупное 艾迪.
     Это тот самый каллиграфический штрих с визитки: в квадрате прописей кисть
     выглядит как письмо от руки, а не как системный шрифт в рамке.
   · Noto Sans SC — рабочие иероглифы: упражнения, таблицы, подписи в интерфейсе,
     где важна разборчивость, а не характер. Serif SC убран намеренно (засечки
     читались как «традиционный Китай», не как школа).
   В платформе иероглифов почти нет — там системный шрифт.

   Django: положить .ttf в staticfiles и заменить url() на {% static %}. */

@import url("https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,400..800;1,400..600&family=Ma+Shan+Zheng&family=Noto+Sans+SC:wght@400;500;700;900&display=swap");

@font-face{font-family:"Days One";src:url("assets/fonts/DaysOne-Regular.ttf") format("truetype");font-weight:400;font-style:normal;font-display:swap}

/* ── eddy/tokens/colors.css ── */
:root{
  /* --- Brand red. Base value sampled from the actual logo file (#DD3333).
     The token file in the Django repo listed #C8322A; that darker, dustier red
     reads as the "seal / oттиск" red and is kept as the hover + print value. --- */
  --red-50:#FDEDEB;--red-100:#F8D4D1;--red-200:#F0AAA5;--red-300:#E67670;
  --red-400:#E04B44;--red-500:#DD3333;--red-600:#C8322A;--red-700:#A32620;--red-800:#7A1D18;

  /* --- Jade (нефрит): secondary brand colour, calm counterweight to the red --- */
  --jade-50:#E9F2EF;--jade-100:#CBE1DA;--jade-200:#9AC6BA;--jade-300:#66A895;
  --jade-500:#2F7A67;--jade-600:#256355;--jade-700:#1B4A40;

  /* --- Signal yellow: attention, not decoration --- */
  --yellow-50:#FEF6E0;--yellow-100:#FBE8B4;--yellow-400:#F2C230;--yellow-600:#C99A12;

  /* --- Gold: taken from the auspicious-cloud artwork on the business card.
     Ornament only, never text or UI. --- */
  --gold-300:#FFD79E;--gold-400:#F7B96B;--gold-500:#EE9F45;

  /* --- Ink + paper neutrals. Warm-neutral, never blue-grey. --- */
  --ink-900:#16181A;--ink-700:#33383D;--ink-600:#4A5058;--ink-500:#6B7278;
  --ink-400:#8E949A;--ink-300:#B6BABE;--ink-200:#D8D6D0;--ink-100:#E8E6E0;
  --paper-50:#FFFFFF;--paper-100:#FBFAF8;--paper-200:#F5F4F0;--paper-300:#EDEBE5;

  /* ================= semantic aliases ================= */
  --accent:var(--red-500);
  --accent-hover:var(--red-600);
  --accent-pressed:var(--red-700);
  --accent-soft:var(--red-50);
  --accent-soft-border:var(--red-100);
  --accent-ink:var(--red-700);

  --secondary:var(--jade-500);
  --secondary-hover:var(--jade-600);
  --secondary-soft:var(--jade-50);

  --text-body:var(--ink-900);
  --text-muted:var(--ink-500);
  --text-subtle:var(--ink-400);
  --text-inverse:#FFFFFF;
  --text-link:var(--red-600);
  --text-link-hover:var(--red-700);

  --surface-page:var(--paper-200);
  --surface-card:var(--paper-50);
  --surface-sunken:var(--paper-300);
  --surface-inverse:var(--ink-900);
  --surface-brand:var(--red-500);
  --surface-brand-deep:var(--red-700);

  --border-subtle:var(--ink-100);
  --border-default:var(--ink-200);
  --border-strong:var(--ink-300);
  --border-focus:var(--red-500);

  --state-disabled-bg:var(--paper-300);
  --state-disabled-text:var(--ink-400);
  --state-disabled-border:var(--ink-200);

  --status-success:var(--jade-500);--status-success-soft:var(--jade-50);
  --status-warning:var(--yellow-400);--status-warning-soft:var(--yellow-50);
  --status-danger:var(--red-600);--status-danger-soft:var(--red-50);
  --status-neutral:var(--ink-500);--status-neutral-soft:var(--paper-300);

  /* money is jade when it arrived, red when it hasn't */
  --money-paid:var(--jade-500);
  --money-due:var(--red-600);

  /* --- Виджет посещений: 9 состояний, значения взяты из живого card.css.
     Цвет здесь несёт смысл — «отменён» и «пропуск без причины» иначе
     выглядят одинаковым серым. --- */
  --visit-attended-bg:#E3F4E6;--visit-attended-fg:#1E7D32;
  --visit-excused-bg:#FFF4D9;--visit-excused-fg:#8A6D1A;
  --visit-unexcused-bg:var(--red-50);--visit-unexcused-fg:var(--red-600);
  --visit-cancelled-bg:#ECECEC;--visit-cancelled-fg:var(--ink-500);
  --visit-rescheduled-bg:#FDF0DA;--visit-rescheduled-fg:#96660F;
  --visit-unmarked-bg:#EEF0F2;--visit-unmarked-fg:var(--ink-500);
  --visit-planned-bg:#E6F0FB;--visit-planned-fg:#1E5AA8;
  --visit-today-col:#FFF6E5;

  /* --- Ранги достижений (card.css: TIER_CLASSES, один набор на все категории) --- */
  --tier-bronze:#B08D57;--tier-bronze-ink:#8A6D3F;
  --tier-silver:#A8B0B8;--tier-silver-ink:#78828C;
  --tier-gold:#D6A419;--tier-gold-ink:#A87B0D;
  --tier-redgold:#C08A2E;--tier-redgold-ink:#8F6318;
  --tier-platinum:#7E8CA0;--tier-platinum-ink:#5A6678;
  --tier-diamond:#5FA8C7;--tier-diamond-ink:#2E7391;
  --tier-emerald:#2F9E6B;--tier-emerald-ink:#1B6A46;
  --tier-jade:var(--jade-500);
  --xp:var(--yellow-600);--xp-bg:var(--yellow-50);

  /* --- Наследие Django-админки. НЕ фирменные цвета: синий #417690 пришёл
     с темой jazzmin. Оставлены только чтобы было видно, что заменяем. --- */
  --legacy-crm-accent:#417690;--legacy-crm-teal:#17A2B8;--legacy-crm-danger:#DC3545;
}

/* ── eddy/tokens/typography.css ── */
:root{
  /* Families. Public site = brand fonts. Cabinets & CRM = system stack, for speed. */
  --font-brand:"Montserrat",-apple-system,"Segoe UI",Roboto,sans-serif;
  --font-display:"Days One","Montserrat",sans-serif; /* логотипное начертание, кириллица есть */
  --font-hanzi:"Noto Sans SC","Montserrat",sans-serif; /* рабочие иероглифы */
  --font-hanzi-brush:"Ma Shan Zheng","Noto Sans SC",cursive; /* кисть: печати, клетка, награды */
  --font-ui:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --font-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  /* Size scale */
  --fs-3xs:11px;--fs-2xs:12px;--fs-xs:13px;--fs-sm:14px;--fs-base:16px;--fs-md:18px;
  /* шаги из черновика школы: meta 13 · small 15 · body 17 · lead 19 */
  --fs-site-small:15px;--fs-site-body:17px;--fs-site-lead:19px;
  --fs-lg:20px;--fs-xl:24px;--fs-2xl:30px;--fs-3xl:36px;--fs-4xl:44px;--fs-5xl:56px;--fs-6xl:68px;

  --lh-tight:1.05; /* @kind other */
  --lh-snug:1.18; /* @kind other */
  --lh-heading:1.25; /* @kind other */
  --lh-normal:1.5; /* @kind other */
  --lh-relaxed:1.65; /* @kind other */

  --fw-regular:400; /* @kind other */
  --fw-medium:500; /* @kind other */
  --fw-semibold:600; /* @kind other */
  --fw-bold:700; /* @kind other */
  --fw-black:800; /* @kind other */

  --ls-tight:-0.02em; /* @kind other */
  --ls-snug:-0.01em; /* @kind other */
  --ls-normal:0; /* @kind other */
  --ls-wide:0.04em; /* @kind other */
  --ls-caps:0.08em; /* @kind other */

  /* Semantic roles — public site */
  --type-hero-size:var(--fs-5xl);
  --type-hero-weight:var(--fw-black); /* @kind other */
  --type-hero-lh:var(--lh-tight); /* @kind other */
  --type-h1-size:var(--fs-4xl);--type-h2-size:var(--fs-2xl);--type-h3-size:var(--fs-lg);
  --type-body-size:var(--fs-site-body);
  --type-body-lh:var(--lh-relaxed); /* @kind other */
  --type-small-size:var(--fs-site-small);
  --type-eyebrow-size:var(--fs-2xs);
  --type-eyebrow-ls:var(--ls-caps); /* @kind other */
  --type-eyebrow-weight:var(--fw-bold); /* @kind other */

  /* Semantic roles — platform (system font, one step tighter) */
  --type-app-title-size:var(--fs-lg);
  --type-app-section-size:var(--fs-base);
  --type-app-body-size:var(--fs-sm);
  --type-app-meta-size:var(--fs-2xs);
  --type-table-size:var(--fs-sm);
  --type-table-head-size:var(--fs-2xs);
}

/* ── eddy/tokens/spacing.css ── */
:root{
  --sp-0:0; /* @kind spacing */--sp-1:2px;--sp-2:4px;--sp-3:6px;--sp-4:8px;--sp-5:12px;--sp-6:16px;
  --sp-7:20px;--sp-8:24px;--sp-9:32px;--sp-10:40px;--sp-11:48px;--sp-12:64px;
  --sp-13:80px;--sp-14:96px;--sp-15:128px;

  /* layout */
  --container-max:1200px;      /* content width inside the 1440 artboard */
  --container-pad:24px;        /* ≥768 */
  --container-pad-sm:16px;     /* 375 */
  --section-y:96px;            /* public-site section rhythm, desktop */
  --section-y-sm:56px;         /* 375 */
  --grid-gutter:24px;
  --grid-columns:12; /* @kind other */

  /* controls */
  --control-h-sm:32px;--control-h:40px;--control-h-lg:48px;--control-h-hero:56px;
  --tap-min:44px;              /* never smaller on touch */
  --row-h:44px;                /* CRM table row */
  --row-h-dense:36px;
  --sidebar-w:240px;
  --topbar-h:56px;

  /* Колонка чекбоксов в списках CRM. От неё считается смещение залипающей второй
     колонки — держим одним числом, чтобы правила не разъехались с фактом. */
  --table-pick-w:52px;
}

/* ── eddy/tokens/radius-shadow.css ── */
:root{
  --r-xs:2px;--r-sm:4px;--r-md:8px;--r-lg:12px;--r-xl:16px;--r-2xl:24px;--r-pill:999px;
  --r-control:8px;   /* buttons, inputs */
  --r-card:12px;     /* cards, panels, modals */
  --r-chip:999px;    /* плашки-чипы */
  --r-seal:4px;      /* печать: near-square, deliberately not round */

  /* Warm ink shadows. Small and low-contrast — the system leans on borders. */
  --sh-xs:0 1px 1px rgba(22,24,26,.05);
  --sh-sm:0 1px 2px rgba(22,24,26,.06),0 1px 1px rgba(22,24,26,.04);
  --sh-md:0 2px 6px rgba(22,24,26,.07),0 1px 2px rgba(22,24,26,.05);
  --sh-lg:0 8px 24px rgba(22,24,26,.10),0 2px 6px rgba(22,24,26,.05);
  --sh-modal:0 24px 64px rgba(22,24,26,.22);
  --sh-inset-top:inset 0 1px 0 rgba(255,255,255,.6);
  --ring-focus:0 0 0 3px rgba(221,51,51,.22);
  --ring-focus-jade:0 0 0 3px rgba(47,122,103,.22);

  --border-w:1px;
  --border-w-strong:2px;
  --rule:1px solid var(--border-default);
}

/* ── eddy/tokens/motion.css ── */
:root{
  /* CSS only, and very little of it. No scroll reveals, no parallax, no cursor effects. */
  --dur-fast:90ms; /* @kind other */      /* hover / active on controls */
  --dur:150ms; /* @kind other */          /* colour + border transitions */
  --dur-slow:220ms; /* @kind other */     /* modal + dropdown entry */
  --ease:cubic-bezier(.2,.6,.3,1); /* @kind other */
  --ease-out:cubic-bezier(0,0,.2,1); /* @kind other */
  --transition-control:background-color var(--dur) var(--ease),border-color var(--dur) var(--ease),color var(--dur) var(--ease),box-shadow var(--dur) var(--ease);
}

/* ── eddy/tokens/base.css ── */
*,*::before,*::after{box-sizing:border-box}
body{margin:0;background:var(--surface-page);color:var(--text-body);font-family:var(--font-brand);font-size:var(--fs-base);line-height:var(--lh-normal);-webkit-font-smoothing:antialiased;text-wrap:pretty}
h1,h2,h3,h4{margin:0;font-weight:var(--fw-bold);line-height:var(--lh-heading);letter-spacing:var(--ls-snug)}
p{margin:0}
a{color:var(--text-link);text-decoration:none}
a:hover{color:var(--text-link-hover);text-decoration:underline}
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}
:lang(zh),.hanzi{font-family:var(--font-hanzi)}
/* Platform surfaces opt into the system font for speed. */
.eddy-app{font-family:var(--font-ui)}

/* ── eddy/components/css/controls.css ── */
/* Buttons, icon buttons, chips, badges.
   Written as plain classes so Django templates can use them without React. */

.eddy-btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-4);font-family:inherit;font-size:var(--fs-sm);font-weight:var(--fw-semibold);line-height:1;letter-spacing:var(--ls-normal);height:var(--control-h);padding:0 var(--sp-7);border:var(--border-w) solid transparent;border-radius:var(--r-control);cursor:pointer;text-decoration:none;white-space:nowrap;transition:var(--transition-control),transform var(--dur-fast) var(--ease)}
.eddy-btn:hover{text-decoration:none}
.eddy-btn:active{transform:translateY(1px)}
.eddy-btn:focus-visible{outline:none;box-shadow:var(--ring-focus)}
.eddy-btn[disabled],.eddy-btn.is-disabled{cursor:not-allowed;transform:none;box-shadow:none;background:var(--state-disabled-bg);color:var(--state-disabled-text);border-color:transparent}
.eddy-btn svg{width:18px;height:18px;flex:none}

.eddy-btn--primary{background:var(--accent);color:var(--text-inverse);box-shadow:var(--sh-xs)}
.eddy-btn--primary:hover{background:var(--accent-hover)}
.eddy-btn--primary:active{background:var(--accent-pressed)}

.eddy-btn--secondary{background:var(--secondary);color:var(--text-inverse)}
.eddy-btn--secondary:hover{background:var(--secondary-hover)}
.eddy-btn--secondary:focus-visible{box-shadow:var(--ring-focus-jade)}

.eddy-btn--outline{background:var(--surface-card);color:var(--text-body);border-color:var(--border-default)}
.eddy-btn--outline:hover{border-color:var(--border-strong);background:var(--paper-100)}
.eddy-btn--outline:active{background:var(--paper-200)}

.eddy-btn--ghost{background:transparent;color:var(--text-body)}
.eddy-btn--ghost:hover{background:rgba(22,24,26,.05)}
.eddy-btn--ghost:active{background:rgba(22,24,26,.09)}

.eddy-btn--danger{background:var(--surface-card);color:var(--status-danger);border-color:var(--red-100)}
.eddy-btn--danger:hover{background:var(--red-50);border-color:var(--red-200)}

.eddy-btn--link{background:transparent;color:var(--text-link);height:auto;padding:0;border:0}
.eddy-btn--link:hover{color:var(--text-link-hover);text-decoration:underline}

.eddy-btn--sm{height:var(--control-h-sm);padding:0 var(--sp-5);font-size:var(--fs-xs)}
.eddy-btn--lg{height:var(--control-h-lg);padding:0 var(--sp-8);font-size:var(--fs-base)}
.eddy-btn--hero{height:var(--control-h-hero);padding:0 var(--sp-9);font-size:var(--fs-md);font-weight:var(--fw-bold)}
.eddy-btn--block{width:100%}
@media (max-width:767px){.eddy-btn{min-height:var(--tap-min)}.eddy-btn--sm{min-height:36px}}

/* icon-only */
.eddy-iconbtn{display:inline-flex;align-items:center;justify-content:center;width:var(--control-h);height:var(--control-h);padding:0;border:var(--border-w) solid transparent;border-radius:var(--r-control);background:transparent;color:var(--ink-600);cursor:pointer;transition:var(--transition-control)}
.eddy-iconbtn:hover{background:rgba(22,24,26,.06);color:var(--text-body)}
.eddy-iconbtn:active{background:rgba(22,24,26,.1)}
.eddy-iconbtn:focus-visible{outline:none;box-shadow:var(--ring-focus)}
.eddy-iconbtn[disabled]{cursor:not-allowed;color:var(--state-disabled-text);background:transparent}
.eddy-iconbtn--outline{border-color:var(--border-default);background:var(--surface-card)}
.eddy-iconbtn--sm{width:var(--control-h-sm);height:var(--control-h-sm)}
.eddy-iconbtn svg{width:18px;height:18px}

/* chips: filters and selectable tags. Pill, 1px border, never shadowed. */
.eddy-chip{display:inline-flex;align-items:center;gap:var(--sp-3);height:var(--control-h-sm);padding:0 var(--sp-5);border:var(--border-w) solid var(--border-default);border-radius:var(--r-chip);background:var(--surface-card);color:var(--ink-600);font-family:inherit;font-size:var(--fs-xs);font-weight:var(--fw-medium);line-height:1;cursor:pointer;transition:var(--transition-control)}
.eddy-chip:hover{border-color:var(--border-strong);color:var(--text-body)}
.eddy-chip.is-active,.eddy-chip[aria-pressed="true"]{background:var(--accent-soft);border-color:var(--red-200);color:var(--accent-ink)}
.eddy-chip.is-active:hover{border-color:var(--red-300)}
.eddy-chip[disabled]{cursor:not-allowed;color:var(--state-disabled-text);background:var(--state-disabled-bg);border-color:var(--state-disabled-border)}
.eddy-chip--jade.is-active{background:var(--secondary-soft);border-color:var(--jade-200);color:var(--jade-700)}
.eddy-chip__count{color:var(--text-subtle);font-variant-numeric:tabular-nums}
.eddy-chip.is-active .eddy-chip__count{color:var(--red-400)}

/* badges: read-only status. Not clickable, no border radius drama. */
.eddy-badge{display:inline-flex;align-items:center;gap:var(--sp-3);padding:2px var(--sp-4);border-radius:var(--r-sm);font-family:inherit;font-size:var(--fs-2xs);font-weight:var(--fw-semibold);line-height:16px;letter-spacing:var(--ls-normal);white-space:nowrap}
.eddy-badge--neutral{background:var(--status-neutral-soft);color:var(--ink-600)}
.eddy-badge--success{background:var(--status-success-soft);color:var(--jade-700)}
.eddy-badge--warning{background:var(--status-warning-soft);color:var(--yellow-600)}
.eddy-badge--danger{background:var(--status-danger-soft);color:var(--red-700)}
.eddy-badge--brand{background:var(--accent);color:var(--text-inverse)}
.eddy-badge__dot{width:6px;height:6px;border-radius:var(--r-pill);background:currentColor;flex:none}

/* ── eddy/components/css/forms.css ── */
/* Inputs, selects, checkboxes, radios, field wrappers. */

.eddy-field{display:flex;flex-direction:column;gap:var(--sp-3)}
.eddy-field__label{font-family:inherit;font-size:var(--fs-xs);font-weight:var(--fw-semibold);color:var(--ink-700)}
.eddy-field__req{color:var(--accent)}
.eddy-field__hint{font-size:var(--fs-2xs);color:var(--text-muted)}
.eddy-field__error{font-size:var(--fs-2xs);color:var(--status-danger);font-weight:var(--fw-medium)}

.eddy-input{width:100%;height:var(--control-h);padding:0 var(--sp-5);font-family:inherit;font-size:var(--fs-sm);color:var(--text-body);background:var(--surface-card);border:var(--border-w) solid var(--border-default);border-radius:var(--r-control);transition:var(--transition-control)}
.eddy-input::placeholder{color:var(--text-subtle)}
.eddy-input:hover{border-color:var(--border-strong)}
.eddy-input:focus{outline:none;border-color:var(--border-focus);box-shadow:var(--ring-focus)}
.eddy-input[disabled]{background:var(--state-disabled-bg);color:var(--state-disabled-text);border-color:var(--state-disabled-border);cursor:not-allowed}
.eddy-input[readonly]{background:var(--paper-200)}
.eddy-input.is-invalid{border-color:var(--status-danger)}
.eddy-input.is-invalid:focus{box-shadow:var(--ring-focus)}
.eddy-input--lg{height:var(--control-h-lg);font-size:var(--fs-base);padding:0 var(--sp-6)}
.eddy-input--sm{height:var(--control-h-sm);font-size:var(--fs-xs)}
textarea.eddy-input{height:auto;min-height:96px;padding:var(--sp-5);line-height:var(--lh-normal);resize:vertical}
@media (max-width:767px){.eddy-input{min-height:var(--tap-min);font-size:var(--fs-base)}}

.eddy-input-wrap{position:relative;display:block}
.eddy-input-wrap .eddy-input{padding-left:38px}
.eddy-input-wrap__icon{position:absolute;left:var(--sp-5);top:50%;transform:translateY(-50%);color:var(--text-subtle);pointer-events:none;display:flex}
.eddy-input-wrap__icon svg{width:16px;height:16px}

.eddy-select{position:relative;display:block}
.eddy-select select{-webkit-appearance:none;appearance:none;width:100%;height:var(--control-h);padding:0 34px 0 var(--sp-5);font-family:inherit;font-size:var(--fs-sm);color:var(--text-body);background:var(--surface-card);border:var(--border-w) solid var(--border-default);border-radius:var(--r-control);cursor:pointer;transition:var(--transition-control)}
.eddy-select select:hover{border-color:var(--border-strong)}
.eddy-select select:focus{outline:none;border-color:var(--border-focus);box-shadow:var(--ring-focus)}
.eddy-select select[disabled]{background:var(--state-disabled-bg);color:var(--state-disabled-text);cursor:not-allowed}
.eddy-select__caret{position:absolute;right:var(--sp-5);top:50%;transform:translateY(-50%);color:var(--ink-500);pointer-events:none;display:flex}
.eddy-select__caret svg{width:16px;height:16px}
.eddy-select select[disabled]+.eddy-select__caret{color:var(--state-disabled-text)}
@media (max-width:767px){.eddy-select select{min-height:var(--tap-min);font-size:var(--fs-base)}}

.eddy-check{display:inline-flex;align-items:flex-start;gap:var(--sp-4);font-family:inherit;font-size:var(--fs-sm);color:var(--text-body);cursor:pointer;line-height:20px}
.eddy-check input{-webkit-appearance:none;appearance:none;margin:0;width:18px;height:18px;flex:none;border:var(--border-w-strong) solid var(--border-strong);border-radius:var(--r-sm);background:var(--surface-card);cursor:pointer;transition:var(--transition-control);position:relative}
.eddy-check input[type="radio"]{border-radius:var(--r-pill)}
.eddy-check input:hover{border-color:var(--ink-500)}
.eddy-check input:focus-visible{outline:none;box-shadow:var(--ring-focus)}
.eddy-check input:checked{background:var(--accent);border-color:var(--accent)}
.eddy-check input[type="checkbox"]:checked::after{content:"";position:absolute;left:4px;top:1px;width:6px;height:10px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(42deg)}
.eddy-check input[type="radio"]:checked::after{content:"";position:absolute;left:3px;top:3px;width:8px;height:8px;border-radius:var(--r-pill);background:#fff}
.eddy-check input[disabled]{background:var(--state-disabled-bg);border-color:var(--state-disabled-border);cursor:not-allowed}
.eddy-check.is-disabled{color:var(--state-disabled-text);cursor:not-allowed}
.eddy-check__sub{display:block;font-size:var(--fs-2xs);color:var(--text-muted)}

/* ── eddy/components/css/surfaces.css ── */
/* Cards, panels, modals, the seal (печать) motif. */

.eddy-card{background:var(--surface-card);border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-card);box-shadow:var(--sh-sm)}
.eddy-card--pad{padding:var(--sp-8)}
.eddy-card--flat{box-shadow:none}
.eddy-card--sunken{background:var(--paper-100);box-shadow:none}
.eddy-card--interactive{cursor:pointer;transition:box-shadow var(--dur) var(--ease),border-color var(--dur) var(--ease)}
.eddy-card--interactive:hover{box-shadow:var(--sh-md);border-color:var(--border-default)}
.eddy-card--interactive:active{box-shadow:var(--sh-xs)}
.eddy-card--interactive.is-disabled{cursor:not-allowed;box-shadow:none;background:var(--paper-200);border-color:var(--border-subtle)}
.eddy-card--interactive.is-disabled *{color:var(--state-disabled-text)!important}
.eddy-card__head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-5);padding:var(--sp-6) var(--sp-8);border-bottom:var(--rule)}
.eddy-card__title{font-size:var(--fs-base);font-weight:var(--fw-bold);letter-spacing:var(--ls-snug)}
.eddy-card__body{padding:var(--sp-8)}
.eddy-card__foot{padding:var(--sp-6) var(--sp-8);border-top:var(--rule);background:var(--paper-100);border-radius:0 0 var(--r-card) var(--r-card)}
/* Полосы-подчёркивания сверху карточки в системе больше нет: приём
   разошёлся по множеству сайтов и читается как след генератора, а не как
   решение. Выделять карточку, когда это правда нужно, следует тем, что
   у системы уже есть, — плашкой, тенью или нефритовым акцентом внутри. */

/* Modal */
.eddy-modal__scrim{position:fixed;inset:0;background:rgba(22,24,26,.48);display:flex;align-items:center;justify-content:center;padding:var(--sp-8);z-index:50;overflow-y:auto;animation:eddy-fade var(--dur-slow) var(--ease-out)}
/* Шапка и подвал закреплены, прокручивается только тело — кнопки «Сохранить» и
   «Отмена» достижимы всегда, даже когда полей больше, чем влезает в экран. */
.eddy-modal{width:100%;max-width:520px;max-height:calc(100vh - 2 * var(--sp-8));display:flex;flex-direction:column;background:var(--surface-card);border-radius:var(--r-card);box-shadow:var(--sh-modal);overflow:hidden;animation:eddy-rise var(--dur-slow) var(--ease-out)}
.eddy-modal--wide{max-width:720px}
.eddy-modal__head{flex:0 0 auto;display:flex;align-items:flex-start;justify-content:space-between;gap:var(--sp-6);padding:var(--sp-8) var(--sp-8) var(--sp-6)}
.eddy-modal__title{font-size:var(--fs-lg);font-weight:var(--fw-bold);letter-spacing:var(--ls-snug)}
.eddy-modal__sub{margin-top:var(--sp-2);font-size:var(--fs-xs);color:var(--text-muted)}
.eddy-modal__body{flex:1 1 auto;min-height:0;overflow-y:auto;padding:0 var(--sp-8) var(--sp-8);font-size:var(--fs-sm);color:var(--ink-700)}
.eddy-modal__foot{flex:0 0 auto;display:flex;justify-content:flex-end;gap:var(--sp-4);padding:var(--sp-6) var(--sp-8);border-top:var(--rule);background:var(--paper-100)}
@keyframes eddy-fade{from{opacity:0}to{opacity:1}}
@keyframes eddy-rise{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@media (max-width:767px){.eddy-modal__scrim{padding:0;align-items:flex-end}.eddy-modal{max-width:none;max-height:92vh;border-radius:var(--r-xl) var(--r-xl) 0 0}.eddy-modal__foot{flex-direction:column-reverse}.eddy-modal__foot .eddy-btn{width:100%}}

/* 田字格 — клетка для прописей: главный фирменный знак системы. Взят из
   черновика токенов школы (.tzg). Один иероглиф в клетке с тонким красным
   крестом — это то, в чём ребёнок пишет первый иероглиф.
   Печать (stamp) — плотный красный блок с 艾迪, как на визитке. */
.eddy-seal{display:inline-flex;align-items:center;justify-content:center;flex:none;position:relative;box-sizing:border-box;background:var(--surface-card);border:1px solid rgba(22,24,26,.3);border-radius:var(--r-seal);overflow:hidden;font-family:var(--font-hanzi);font-weight:500;line-height:1;color:var(--ink-900)}
.eddy-seal::before,.eddy-seal::after{content:"";position:absolute;background:var(--accent);opacity:.3}
.eddy-seal::before{left:0;right:0;top:50%;height:1px}
.eddy-seal::after{top:0;bottom:0;left:50%;width:1px}
/* Кисть в клетке прописей. Начертание Ma Shan Zheng рисует иероглиф свободнее,
   чем системный шрифт: штрих живой, знак не упирается в рамку. Оптически кисть
   мельче наборного шрифта, поэтому кегль поднят и знак чуть смещён вверх. */
.eddy-seal__char{position:relative;display:block;font-family:var(--font-hanzi-brush);font-weight:400;font-size:.92em;line-height:.86;letter-spacing:0;transform:translateY(-.03em)}
.eddy-seal--sm{width:28px;height:28px;font-size:28px}
.eddy-seal--md{width:44px;height:44px;font-size:44px}
.eddy-seal--lg{width:72px;height:72px;font-size:72px}
.eddy-seal--xl{width:120px;height:120px;font-size:120px}
.eddy-seal--red .eddy-seal__char{color:var(--accent)}
.eddy-seal--jade .eddy-seal__char{color:var(--secondary)}
/* печать: заливка, без клетки */
.eddy-seal--stamp{background:var(--accent);border-color:transparent;color:#fff}
.eddy-seal--stamp::before,.eddy-seal--stamp::after{display:none}
.eddy-seal--stamp .eddy-seal__char{color:#fff;font-weight:400;font-size:.5em;line-height:1.05;transform:none;letter-spacing:.02em;writing-mode:vertical-rl;text-orientation:upright}
.eddy-seal--stamp.eddy-seal--wide .eddy-seal__char{writing-mode:horizontal-tb;font-size:.52em}
.eddy-seal--stamp.eddy-seal--outline{background:transparent;box-shadow:inset 0 0 0 2px var(--accent)}
.eddy-seal--stamp.eddy-seal--outline .eddy-seal__char{color:var(--accent)}

/* Сетка прописей как фон — «gridpaper» из черновика школы. Только на
   светлых блоках, только под контентом, никогда под таблицей. */
.eddy-gridpaper{background-image:linear-gradient(rgba(22,24,26,.06) 1px,transparent 1px),linear-gradient(90deg,rgba(22,24,26,.06) 1px,transparent 1px);background-size:76px 76px}

/* Avatar */
.eddy-avatar{display:inline-flex;align-items:center;justify-content:center;border-radius:var(--r-pill);background:var(--paper-300);color:var(--ink-600);font-family:inherit;font-weight:var(--fw-bold);overflow:hidden;flex:none}
.eddy-avatar img{width:100%;height:100%;object-fit:cover}
.eddy-avatar--xs{width:24px;height:24px;font-size:var(--fs-3xs)}
.eddy-avatar--sm{width:32px;height:32px;font-size:var(--fs-2xs)}
.eddy-avatar--md{width:40px;height:40px;font-size:var(--fs-sm)}
.eddy-avatar--lg{width:56px;height:56px;font-size:var(--fs-md)}
.eddy-avatar--xl{width:88px;height:88px;font-size:var(--fs-xl)}
.eddy-avatar--brand{background:var(--accent-soft);color:var(--accent-ink)}
.eddy-avatar--jade{background:var(--secondary-soft);color:var(--jade-700)}

/* ── eddy/components/css/table.css ── */
/* Tables stay tables. Hundreds of rows, sortable headers, sticky header,
   horizontal scroll at 375 with the name column pinned. Never "cards instead of rows". */

.eddy-table-wrap{width:100%;overflow-x:auto;background:var(--surface-card);border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-card)}
.eddy-table{width:100%;min-width:640px;border-collapse:separate;border-spacing:0;font-family:inherit;font-size:var(--type-table-size);color:var(--text-body)}
.eddy-table thead th{position:sticky;top:0;z-index:2;background:var(--paper-100);border-bottom:var(--border-w) solid var(--border-default);padding:var(--sp-4) var(--sp-6);text-align:left;font-size:var(--type-table-head-size);font-weight:var(--fw-semibold);letter-spacing:var(--ls-wide);text-transform:uppercase;color:var(--ink-500);white-space:nowrap}
.eddy-table tbody td{padding:0 var(--sp-6);height:var(--row-h);border-bottom:var(--border-w) solid var(--border-subtle);vertical-align:middle}
.eddy-table tbody tr:last-child td{border-bottom:0}
.eddy-table tbody tr:hover td{background:var(--paper-100)}
.eddy-table tbody tr.is-selected td{background:var(--accent-soft)}
.eddy-table tbody tr.is-disabled td{color:var(--state-disabled-text);background:var(--paper-200)}
.eddy-table--dense tbody td{height:var(--row-h-dense)}
.eddy-table .num{text-align:right;font-variant-numeric:tabular-nums}
.eddy-table .nowrap{white-space:nowrap}
/* Списки CRM на сотни строк: ни одна ячейка не переносится, поэтому все строки
   одной высоты и числа стоят на одной линии. Ширину набирает содержимое,
   лишнее уезжает в горизонтальную прокрутку .eddy-tablewrap. */
.eddy-table--nowrap thead th,.eddy-table--nowrap tbody td{white-space:nowrap}
.eddy-table__sort{display:inline-flex;align-items:center;gap:var(--sp-2);background:none;border:0;padding:0;font:inherit;letter-spacing:inherit;text-transform:inherit;color:inherit;cursor:pointer}
.eddy-table__sort:hover{color:var(--text-body)}
.eddy-table__sort[aria-sort="ascending"],.eddy-table__sort[aria-sort="descending"]{color:var(--accent-ink)}
.eddy-table__sort svg{width:12px;height:12px;opacity:.55}
.eddy-table__sort[aria-sort="none"] svg{opacity:.25}
.eddy-table__primary{font-weight:var(--fw-semibold)}
.eddy-table__meta{display:block;font-size:var(--fs-3xs);color:var(--text-muted);font-weight:var(--fw-regular)}
.eddy-table__empty{padding:var(--sp-11) var(--sp-6);text-align:center;color:var(--text-muted);font-size:var(--fs-sm)}
.eddy-table__foot{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-5);padding:var(--sp-5) var(--sp-6);border-top:var(--rule);font-size:var(--fs-2xs);color:var(--text-muted)}
.eddy-table col.w-check{width:40px}
.eddy-table th.check,.eddy-table td.check{padding-right:0}

@media (max-width:767px){
  .eddy-table{min-width:560px}
}

/* Залипание первых колонок — один блок и один источник ширины.
   Колонка чекбоксов всегда --pick-w: без min-width её раздувает min-content
   (чекбокс плюс два паддинга), и любое смещение второй колонки расходится с фактом. */
.eddy-table__pick{width:var(--table-pick-w);min-width:var(--table-pick-w);max-width:var(--table-pick-w);text-align:center}
@media (max-width:1023px){
  .eddy-table--sticky1 thead th:nth-child(1),.eddy-table--sticky1 tbody td:nth-child(1){position:sticky;left:0;z-index:1;background:var(--surface-card)}
  .eddy-table--sticky1 thead th:nth-child(2),.eddy-table--sticky1 tbody td:nth-child(2){position:sticky;left:var(--table-pick-w);z-index:1;background:var(--surface-card);box-shadow:1px 0 0 var(--border-subtle)}
  .eddy-table--sticky1 thead th:nth-child(1),.eddy-table--sticky1 thead th:nth-child(2){z-index:3;background:var(--paper-100)}
  .eddy-table--sticky1 tbody tr:hover td:nth-child(1),.eddy-table--sticky1 tbody tr:hover td:nth-child(2){background:var(--paper-100)}
}

/* Без колонки выбора залипает первая же колонка — тот же брейкпоинт, что и у --sticky1. */
@media (max-width:1023px){
  .eddy-table--sticky thead th:first-child,.eddy-table--sticky tbody td:first-child{position:sticky;left:0;z-index:1;background:var(--surface-card);box-shadow:1px 0 0 var(--border-subtle)}
  .eddy-table--sticky thead th:first-child{z-index:3;background:var(--paper-100)}
  .eddy-table--sticky tbody tr:hover td:first-child{background:var(--paper-100)}
}

/* ── eddy/components/css/site.css ── */
/* Public site (eddy.pw) shell + section furniture. Montserrat, generous rhythm. */

.eddy-site{font-family:var(--font-brand);background:var(--surface-page);color:var(--text-body)}
.eddy-container{max-width:var(--container-max);margin:0 auto;padding:0 var(--container-pad)}
.eddy-section{padding:var(--section-y) 0}
.eddy-section--tight{padding:calc(var(--section-y) * .6) 0}
.eddy-section--paper{background:var(--surface-page)}
.eddy-section--white{background:var(--surface-card)}
@media (max-width:767px){.eddy-container{padding:0 var(--container-pad-sm)}.eddy-section{padding:var(--section-y-sm) 0}}

.eddy-eyebrow{font-size:var(--type-eyebrow-size);font-weight:var(--type-eyebrow-weight);letter-spacing:var(--type-eyebrow-ls);text-transform:uppercase;color:var(--accent)}
.eddy-eyebrow--jade{color:var(--secondary)}
.eddy-eyebrow--inverse{color:var(--gold-300)}
.eddy-h1{font-size:var(--type-h1-size);font-weight:var(--fw-black);line-height:var(--lh-snug);letter-spacing:var(--ls-tight)}
.eddy-h2{font-size:var(--type-h2-size);font-weight:var(--fw-bold);line-height:var(--lh-heading);letter-spacing:var(--ls-tight)}
.eddy-h3{font-size:var(--type-h3-size);font-weight:var(--fw-bold);line-height:var(--lh-heading)}
.eddy-lead{font-size:var(--fs-md);line-height:var(--lh-relaxed);color:var(--ink-600)}
.eddy-body{font-size:var(--type-body-size);line-height:var(--type-body-lh);color:var(--ink-700)}
.eddy-small{font-size:var(--fs-sm);color:var(--text-muted)}
.eddy-hero-title{font-size:var(--type-hero-size);font-weight:var(--fw-black);line-height:var(--lh-tight);letter-spacing:var(--ls-tight)}
@media (max-width:767px){.eddy-hero-title{font-size:var(--fs-3xl)}.eddy-h1{font-size:var(--fs-2xl)}.eddy-h2{font-size:var(--fs-xl)}.eddy-h3{font-size:var(--fs-md)}.eddy-lead,.eddy-body{font-size:var(--fs-base)}}

/* header */
.eddy-header{position:sticky;top:0;z-index:30;background:rgba(255,255,255,.92);backdrop-filter:blur(8px);border-bottom:var(--border-w) solid var(--border-subtle)}
.eddy-header__row{display:flex;align-items:center;gap:var(--sp-9);height:72px}
.eddy-nav{display:flex;align-items:center;gap:var(--sp-8);margin-left:auto}
.eddy-nav a{font-size:var(--fs-sm);font-weight:var(--fw-medium);color:var(--ink-700);text-decoration:none;padding:var(--sp-3) 0;border-bottom:2px solid transparent}
.eddy-nav a:hover{color:var(--accent);text-decoration:none}
.eddy-nav a.is-active{color:var(--text-body);border-bottom-color:var(--accent)}
.eddy-header__actions{display:flex;align-items:center;gap:var(--sp-5)}
.eddy-burger{display:none;margin-left:auto}
@media (max-width:1023px){.eddy-nav{display:none}.eddy-header__actions .eddy-btn--outline{display:none}.eddy-burger{display:inline-flex}.eddy-header__row{height:60px;gap:var(--sp-5)}}

/* brand surfaces: the red block with the 艾迪 clouds, straight off the business card */
.eddy-brandblock{position:relative;background:var(--surface-brand);color:#fff;overflow:hidden}
.eddy-brandblock--deep{background:var(--surface-brand-deep)}
.eddy-brandblock__clouds{position:absolute;right:-40px;bottom:-30px;width:420px;opacity:.22;pointer-events:none;user-select:none}
.eddy-brandblock__hanzi{position:absolute;right:4%;top:50%;transform:translateY(-50%);font-family:var(--font-hanzi);font-weight:700;font-size:320px;line-height:1;color:rgba(255,255,255,.10);pointer-events:none;user-select:none}
.eddy-brandblock a{color:#fff}

/* footer */
.eddy-footer{background:var(--ink-900);color:rgba(255,255,255,.72);padding:var(--sp-12) 0 var(--sp-9)}
.eddy-footer a{color:rgba(255,255,255,.72);font-size:var(--fs-sm)}
.eddy-footer a:hover{color:#fff}
.eddy-footer__grid{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:var(--sp-9)}
.eddy-footer__title{font-size:var(--fs-2xs);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);text-transform:uppercase;color:rgba(255,255,255,.45);margin-bottom:var(--sp-5)}
.eddy-footer__col{display:flex;flex-direction:column;gap:var(--sp-4)}
.eddy-footer__bottom{margin-top:var(--sp-11);padding-top:var(--sp-6);border-top:1px solid rgba(255,255,255,.12);font-size:var(--fs-2xs);color:rgba(255,255,255,.45);display:flex;justify-content:space-between;gap:var(--sp-6)}
@media (max-width:767px){.eddy-footer__grid{grid-template-columns:1fr 1fr}.eddy-footer__bottom{flex-direction:column}}

/* hero: text left, art right; art drops below at 1024 and shrinks at 375 */
.eddy-hero{display:grid;grid-template-columns:minmax(0,1fr) 360px;gap:var(--sp-11);align-items:center}
.eddy-hero__art{position:relative}
@media (max-width:1023px){.eddy-hero{grid-template-columns:1fr}.eddy-hero__art{max-width:260px}}
@media (max-width:767px){.eddy-hero__art{max-width:180px;margin:0 auto}}

/* Image placeholders. The brand has no photo library yet: every photo slot is an
   honest placeholder that says what belongs there. Replace with real photography. */
.eddy-ph{position:relative;display:flex;align-items:center;justify-content:center;text-align:center;background:var(--paper-300);border:1px dashed var(--border-strong);border-radius:var(--r-card);color:var(--text-subtle);font-size:var(--fs-2xs);padding:var(--sp-5);overflow:hidden}
.eddy-ph--onred{background:rgba(255,255,255,.10);border-color:rgba(255,255,255,.35);color:rgba(255,255,255,.8)}
.eddy-ph--circle{border-radius:var(--r-pill)}

/* kit layouts */
.eddy-teacher{display:grid;grid-template-columns:340px minmax(0,1fr);gap:var(--sp-11);align-items:start}
.eddy-contacts{display:grid;grid-template-columns:minmax(0,1fr) 520px;gap:var(--sp-11);align-items:start}
.eddy-form-2{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-6)}
@media (max-width:1023px){.eddy-teacher,.eddy-contacts{grid-template-columns:1fr;gap:var(--sp-8)}}
@media (max-width:767px){.eddy-form-2{grid-template-columns:1fr}}

/* small utilities used by the kits */
.eddy-grid{display:grid;gap:var(--grid-gutter)}
.eddy-grid--3{grid-template-columns:repeat(3,1fr)}
.eddy-grid--4{grid-template-columns:repeat(4,1fr)}
.eddy-grid--2{grid-template-columns:repeat(2,1fr)}
.eddy-grid--5{grid-template-columns:repeat(5,1fr)}
@media (max-width:1279px){.eddy-grid--5{grid-template-columns:repeat(3,1fr)}}
@media (max-width:767px){.eddy-grid--5{grid-template-columns:1fr}}
@media (max-width:1023px){.eddy-grid--4{grid-template-columns:repeat(2,1fr)}}
@media (max-width:767px){.eddy-grid--2,.eddy-grid--3,.eddy-grid--4{grid-template-columns:1fr}}
.eddy-stack{display:flex;flex-direction:column}
.eddy-row{display:flex;align-items:center}
.eddy-rule{height:1px;background:var(--border-subtle);border:0;margin:0}

/* Фотографии: ряд с горизонтальной прокруткой и сетка. Кадры школы — тёплый свет,
   реальные люди; кроп 3:2, подпись под кадром мелким кеглем. */
.eddy-photorow{display:flex;gap:var(--sp-5);overflow-x:auto;padding-bottom:var(--sp-4)}
.eddy-photo{margin:0;flex:none;border-radius:var(--r-card);overflow:hidden;background:var(--paper-300);position:relative}
.eddy-photo img{display:block;height:100%;width:auto;max-width:none;object-fit:cover}
.eddy-photo figcaption{position:absolute;left:0;right:0;bottom:0;padding:var(--sp-6) var(--sp-5) var(--sp-4);color:#fff;font-size:var(--fs-2xs);line-height:1.4;background:linear-gradient(to top,rgba(22,24,26,.72),rgba(22,24,26,0))}
.eddy-photogrid{display:grid;grid-template-columns:repeat(4,1fr);grid-auto-rows:170px;gap:var(--sp-5)}
.eddy-photogrid figure{margin:0;border-radius:var(--r-card);overflow:hidden;background:var(--paper-300)}
.eddy-photogrid img{width:100%;height:100%;object-fit:cover;display:block}
.eddy-photogrid .wide{grid-column:span 2}
.eddy-photogrid .tall{grid-row:span 2}
@media (max-width:1023px){.eddy-photogrid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:767px){.eddy-photogrid{grid-template-columns:1fr;grid-auto-rows:200px}.eddy-photogrid .wide{grid-column:span 1}}

/* Плашки доверия: награда, лицензия, рейтинг. Логотип или знак слева, факт справа. */
.eddy-trust{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-5)}
.eddy-trust__item{display:flex;gap:var(--sp-5);align-items:flex-start;padding:var(--sp-6);background:var(--surface-card);border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-card)}
.eddy-trust__item img{width:72px;height:auto;max-height:96px;object-fit:contain;flex:none}
.eddy-trust__val{font-size:var(--fs-lg);font-weight:var(--fw-bold);line-height:1.15;letter-spacing:var(--ls-snug)}
.eddy-trust__cap{margin-top:var(--sp-3);font-size:var(--fs-2xs);color:var(--text-muted);line-height:1.45}
@media (max-width:1023px){.eddy-trust{grid-template-columns:repeat(2,1fr)}}
@media (max-width:767px){.eddy-trust{grid-template-columns:1fr}}

/* Логотипы партнёров и заказчиков перевода: серые ячейки одной высоты. */
.eddy-logos{display:grid;grid-template-columns:repeat(5,1fr);gap:var(--sp-5)}
.eddy-logos > *{height:88px;display:grid;place-items:center;padding:var(--sp-5);border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-md);background:#fff;font-size:var(--fs-2xs);color:var(--text-subtle);text-align:center;line-height:1.35}
/* Логотипы заказчиков приходят разноцветными и разного формата: выравниваем по
   высоте бокса, ничего не перекрашиваем — чужой знак трогать нельзя. */
.eddy-logos img{max-width:100%;max-height:56px;width:auto;height:auto;object-fit:contain;display:block;mix-blend-mode:multiply}
@media (max-width:1023px){.eddy-logos{grid-template-columns:repeat(3,1fr)}}
@media (max-width:767px){.eddy-logos{grid-template-columns:repeat(2,1fr)}}

/* Ссылка на видео в СМИ: кадр-плейсхолдер + канал и тема. */
.eddy-media{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-5)}
.eddy-media__item{display:flex;gap:var(--sp-5);align-items:center;padding:var(--sp-5) var(--sp-6);border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-card);background:var(--surface-card);text-decoration:none;min-height:var(--tap-min)}
.eddy-media__item:hover{border-color:var(--border-strong);text-decoration:none}
.eddy-media__play{width:36px;height:36px;border-radius:var(--r-pill);background:var(--accent-soft);color:var(--accent);display:grid;place-items:center;flex:none}
/* `display:block` обязателен: строчными они ложатся на одну строку и
   налезают друг на друга — на телефоне название канала перекрывало
   заголовок сюжета (видно только на живой странице). */
.eddy-media__ch{display:block;font-size:var(--fs-site-small);font-weight:var(--fw-semibold);color:var(--text-body)}
.eddy-media__t{display:block;margin-top:2px;font-size:var(--fs-2xs);color:var(--text-muted);line-height:1.4}
@media (max-width:1023px){.eddy-media{grid-template-columns:repeat(2,1fr)}}
@media (max-width:767px){.eddy-media{grid-template-columns:1fr}}

/* ── eddy/components/css/app.css ── */
/* Platform (app.eddy.pw): CRM, teacher / student / parent cabinets.
   System font, denser scale, borders over shadows. Reference level of order: progressme. */

.eddy-app{font-family:var(--font-ui);background:var(--surface-page);color:var(--text-body);min-height:100%}
/* minmax(0,1fr), не 1fr: иначе колонка контента растягивается под собственную
   ширину таблицы и наружу уезжает вся оболочка — топбар, тулбар, срезы. Ноль в
   минимуме оставляет прокрутку внутри .eddy-tablewrap, где она и должна быть. */
.eddy-app__layout{display:grid;grid-template-columns:var(--sidebar-w) minmax(0,1fr);min-height:100vh}
@media (max-width:1023px){.eddy-app__layout{grid-template-columns:minmax(0,1fr)}}

.eddy-side{background:var(--surface-card);border-right:var(--border-w) solid var(--border-subtle);display:flex;flex-direction:column;gap:var(--sp-2)}
.eddy-side__brand{display:flex;align-items:center;gap:var(--sp-5);height:var(--topbar-h);padding:0 var(--sp-6);border-bottom:var(--border-w) solid var(--border-subtle)}
.eddy-side__group{padding:var(--sp-6) var(--sp-4) var(--sp-2)}
.eddy-side__grouptitle{padding:0 var(--sp-4) var(--sp-4);font-size:var(--fs-3xs);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--text-subtle)}
.eddy-side__link{display:flex;align-items:center;gap:var(--sp-5);padding:var(--sp-4) var(--sp-5);margin:0 var(--sp-4) 2px;border-radius:var(--r-md);font-size:var(--type-app-body-size);font-weight:var(--fw-medium);color:var(--ink-700);text-decoration:none;cursor:pointer;transition:var(--transition-control)}
.eddy-side__link:hover{background:var(--paper-200);color:var(--text-body);text-decoration:none}
.eddy-side__link.is-active{background:var(--accent-soft);color:var(--accent-ink);font-weight:var(--fw-semibold)}
.eddy-side__link svg{width:18px;height:18px;flex:none;opacity:.8}
.eddy-side__count{margin-left:auto;font-size:var(--fs-3xs);color:var(--text-subtle);font-variant-numeric:tabular-nums}
.eddy-side__foot{margin-top:auto;padding:var(--sp-5);border-top:var(--border-w) solid var(--border-subtle)}

.eddy-topbar{display:flex;align-items:center;gap:var(--sp-6);height:var(--topbar-h);padding:0 var(--sp-8);background:var(--surface-card);border-bottom:var(--border-w) solid var(--border-subtle);position:sticky;top:0;z-index:20}
.eddy-topbar__title{font-size:var(--type-app-title-size);font-weight:var(--fw-bold);letter-spacing:var(--ls-snug)}
.eddy-topbar__spacer{margin-left:auto}
@media (max-width:767px){.eddy-topbar{padding:0 var(--sp-5)}.eddy-topbar__title{font-size:var(--fs-base)}}

.eddy-main{padding:var(--sp-8)}
@media (max-width:767px){.eddy-main{padding:var(--sp-5)}}
.eddy-page-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--sp-6);margin-bottom:var(--sp-7)}
.eddy-page-head__sub{margin-top:var(--sp-2);font-size:var(--type-app-meta-size);color:var(--text-muted)}

.eddy-toolbar{display:flex;align-items:center;gap:var(--sp-4);flex-wrap:wrap;margin-bottom:var(--sp-6)}
.eddy-toolbar__spacer{margin-left:auto}

/* tabs (used in the student card and the schedule) */
.eddy-tabs{display:flex;gap:var(--sp-7);border-bottom:var(--border-w) solid var(--border-default);overflow-x:auto}
.eddy-tab{padding:var(--sp-5) 0;border:0;border-bottom:2px solid transparent;background:none;font:inherit;font-size:var(--type-app-body-size);font-weight:var(--fw-medium);color:var(--text-muted);cursor:pointer;white-space:nowrap;transition:var(--transition-control)}
.eddy-tab:hover{color:var(--text-body)}
.eddy-tab.is-active{color:var(--text-body);font-weight:var(--fw-semibold);border-bottom-color:var(--accent)}
.eddy-tab[disabled]{color:var(--state-disabled-text);cursor:not-allowed}

/* metric tiles: only real school numbers — ученики, деньги, уроки, посещаемость */
/* Плашка-показатель. Три строки фиксированной высоты, поэтому в ряду все числа
   стоят на одной линии независимо от длины подписи и примечания. Значение не
   переносится: длинное значение — не число, для него вариант --text. */
.eddy-stat{display:grid;grid-template-rows:2.7em 1.35em 1.35em;align-content:start;height:100%;background:var(--surface-card);border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-card);padding:var(--sp-6) var(--sp-7)}
.eddy-stat__label{font-size:var(--type-app-meta-size);line-height:1.35;color:var(--text-muted);overflow:hidden}
.eddy-stat__value{align-self:end;font-size:var(--fs-xl);font-weight:var(--fw-bold);letter-spacing:var(--ls-snug);font-variant-numeric:tabular-nums;line-height:1.35;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.eddy-stat__note{align-self:end;font-size:var(--fs-3xs);line-height:1.35;color:var(--text-subtle);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Не-числовое значение (имя, ссылка): обычный размер текста, в две строки. */
.eddy-stat--text{grid-template-rows:2.7em 2.7em 1.35em}
.eddy-stat--text .eddy-stat__value{font-size:var(--type-app-body-size);font-weight:var(--fw-semibold);white-space:normal;align-self:end;line-height:1.35}

/* definition list used across cabinet cards */
.eddy-dl{display:grid;grid-template-columns:auto 1fr;gap:var(--sp-4) var(--sp-6);font-size:var(--type-app-body-size)}
.eddy-dl dt{color:var(--text-muted)}
.eddy-dl dd{margin:0;font-weight:var(--fw-medium)}

/* schedule grid */
.eddy-sched{display:grid;grid-template-columns:56px repeat(6,1fr);border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-card);background:var(--surface-card);overflow:hidden}
.eddy-sched__head{padding:var(--sp-4) var(--sp-5);background:var(--paper-100);border-bottom:var(--border-w) solid var(--border-default);font-size:var(--type-app-meta-size);font-weight:var(--fw-semibold);color:var(--ink-600)}
.eddy-sched__head.is-today{color:var(--accent-ink);box-shadow:inset 0 -2px 0 var(--accent)}
.eddy-sched__time{padding:var(--sp-4) var(--sp-4);border-right:var(--border-w) solid var(--border-subtle);border-bottom:var(--border-w) solid var(--border-subtle);font-size:var(--fs-3xs);color:var(--text-subtle);text-align:right;font-variant-numeric:tabular-nums}
.eddy-sched__cell{border-right:var(--border-w) solid var(--border-subtle);border-bottom:var(--border-w) solid var(--border-subtle);padding:var(--sp-2);min-height:64px;display:flex;flex-direction:column;gap:var(--sp-2)}
.eddy-lesson{display:block;width:100%;text-align:left;border:0;border-left:3px solid var(--secondary);background:var(--jade-50);border-radius:var(--r-sm);padding:var(--sp-3) var(--sp-4);font:inherit;font-size:var(--fs-3xs);line-height:1.3;color:var(--jade-700);cursor:pointer;transition:var(--transition-control)}
.eddy-lesson:hover{background:var(--jade-100)}
.eddy-lesson b{display:block;font-size:var(--type-app-meta-size);font-weight:var(--fw-semibold);color:var(--jade-700)}
.eddy-lesson--brand{border-left-color:var(--accent);background:var(--red-50);color:var(--red-700)}
.eddy-lesson--brand b{color:var(--red-700)}
.eddy-lesson--brand:hover{background:var(--red-100)}
.eddy-lesson--muted{border-left-color:var(--ink-300);background:var(--paper-200);color:var(--ink-600)}
.eddy-lesson--muted b{color:var(--ink-700)}

/* Cabinet / CRM layout helpers used by the screens */
.eddy-app__burger{display:none}
.eddy-statrow{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-5)}
.eddy-card-2{display:grid;grid-template-columns:minmax(0,1fr) 380px;gap:var(--sp-5)}
.eddy-family-2{display:grid;grid-template-columns:minmax(0,1fr) 360px;gap:var(--sp-5)}
.eddy-childrow{display:grid;grid-template-columns:auto minmax(0,1.2fr) minmax(0,1fr) auto;gap:var(--sp-7);align-items:center}
.eddy-childrow__act{display:flex;flex-direction:column;gap:var(--sp-4)}
.eddy-sched--mobile{display:none}
@media (max-width:1023px){
  .eddy-side{display:none}
  .eddy-app__burger{display:inline-flex}
  .eddy-childrow{grid-template-columns:auto minmax(0,1fr)}
  .eddy-childrow__dl,.eddy-childrow__act{grid-column:1 / -1}
  .eddy-childrow__act{flex-direction:row}
}
@media (max-width:900px){.eddy-sched--desktop{display:none}.eddy-sched--mobile{display:block}}
@media (max-width:767px){
  .eddy-statrow{grid-template-columns:1fr 1fr}
  .eddy-card-2,.eddy-family-2{grid-template-columns:1fr}
  .eddy-page-head{flex-direction:column;align-items:stretch;gap:var(--sp-5)}
}

/* ============ Виджет посещений (карточка ученика, кабинеты) ============
   Девять состояний, значения цветов — из живого card.css. Ячейка 44×44:
   это и тач-зона, и ровная сетка. «Не записан» — пустая клетка с пунктиром,
   это не то же самое, что «не отмечен». */
.eddy-visits{display:flex;flex-wrap:wrap;gap:6px}
.eddy-visit{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;width:44px;height:44px;border-radius:6px;background:var(--visit-unmarked-bg);color:var(--visit-unmarked-fg);font-size:10px;line-height:1.1;border:0;cursor:pointer;font-family:inherit}
.eddy-visit__wd{text-transform:uppercase;font-size:9px;opacity:.75}
.eddy-visit__d{font-weight:var(--fw-semibold)}
.eddy-visit--attended{background:var(--visit-attended-bg);color:var(--visit-attended-fg)}
.eddy-visit--excused{background:var(--visit-excused-bg);color:var(--visit-excused-fg)}
.eddy-visit--unexcused{background:var(--visit-unexcused-bg);color:var(--visit-unexcused-fg)}
.eddy-visit--cancelled{background:var(--visit-cancelled-bg);color:var(--visit-cancelled-fg);text-decoration:line-through}
.eddy-visit--rescheduled{background:var(--visit-rescheduled-bg);color:var(--visit-rescheduled-fg)}
.eddy-visit--planned{background:var(--visit-planned-bg);color:var(--visit-planned-fg)}
.eddy-visit--none{background:transparent;border:1px dashed var(--border-default);color:var(--text-subtle)}
.eddy-visit--today{outline:2px solid var(--accent);outline-offset:1px}
.eddy-visit-tag{display:inline-block;padding:2px 8px;border-radius:10px;font-size:var(--fs-2xs);font-weight:var(--fw-semibold);white-space:nowrap;background:var(--visit-unmarked-bg);color:var(--visit-unmarked-fg)}
.eddy-visit-tag--attended{background:var(--visit-attended-bg);color:var(--visit-attended-fg)}
.eddy-visit-tag--excused{background:var(--visit-excused-bg);color:var(--visit-excused-fg)}
.eddy-visit-tag--unexcused{background:var(--visit-unexcused-bg);color:var(--visit-unexcused-fg)}
.eddy-visit-tag--planned{background:var(--visit-planned-bg);color:var(--visit-planned-fg)}
.eddy-visit-tag--cancelled{background:var(--visit-cancelled-bg);color:var(--visit-cancelled-fg)}

/* ============ Строка-пилюли: «Цель · Интересы · Курс · Ответственный» ====
   Незаполненное значение подсвечено жёлтым — дизайн подталкивает заполнить. */
.eddy-pills{display:flex;flex-wrap:wrap;gap:var(--sp-4)}
.eddy-pill{display:inline-flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-5);border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-pill);background:var(--surface-card);font-size:var(--type-app-body-size);color:var(--ink-600);white-space:nowrap}
.eddy-pill b{color:var(--text-body);font-weight:var(--fw-semibold)}
.eddy-pill__empty{padding:1px var(--sp-4);border-radius:var(--r-sm);background:var(--yellow-50);color:var(--yellow-600);font-size:var(--fs-2xs);font-weight:var(--fw-semibold)}
.eddy-pill__add{color:var(--text-link);font-weight:var(--fw-bold);cursor:pointer}

/* ============ Тулбар + вкладки-срезы: главный повторяющийся макет CRM ==== */
.eddy-viewswitch{display:flex;gap:var(--sp-2);background:var(--paper-200);padding:3px;border-radius:var(--r-control);width:max-content}
.eddy-viewswitch button{border:0;background:none;font:inherit;font-size:var(--type-app-body-size);font-weight:var(--fw-medium);color:var(--ink-600);padding:var(--sp-3) var(--sp-6);border-radius:calc(var(--r-control) - 2px);cursor:pointer;white-space:nowrap}
.eddy-viewswitch button:hover{color:var(--text-body)}
.eddy-viewswitch button.is-active{background:var(--surface-card);color:var(--text-body);font-weight:var(--fw-semibold);box-shadow:var(--sh-xs)}
.eddy-slices{display:flex;gap:var(--sp-3);overflow-x:auto;padding-bottom:var(--sp-2)}

/* ============ Канбан: задачи и лиды ============ */
.eddy-kanban{display:flex;gap:var(--sp-5);overflow-x:auto;padding-bottom:var(--sp-5);align-items:flex-start}
.eddy-kanban__col{flex:0 0 268px;background:var(--paper-100);border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-card);padding:var(--sp-5)}
.eddy-kanban__head{display:flex;align-items:center;gap:var(--sp-4);margin-bottom:var(--sp-5);font-size:var(--fs-2xs);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--ink-600)}
.eddy-kanban__count{margin-left:auto;color:var(--text-subtle);font-variant-numeric:tabular-nums}
.eddy-kanban__cards{display:flex;flex-direction:column;gap:var(--sp-4)}
.eddy-kancard{background:var(--surface-card);border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-md);padding:var(--sp-5);box-shadow:var(--sh-xs);cursor:pointer;transition:var(--transition-control)}
.eddy-kancard:hover{box-shadow:var(--sh-md)}
.eddy-kancard__title{font-size:var(--type-app-body-size);font-weight:var(--fw-semibold);line-height:1.35}
.eddy-kancard__meta{margin-top:var(--sp-3);font-size:var(--fs-2xs);color:var(--text-muted)}
.eddy-kancard__unassigned{color:var(--status-danger);font-size:var(--fs-2xs);font-weight:var(--fw-medium)}

/* ============ Прогресс и награды (кабинет ребёнка) ============ */
.eddy-progress{height:8px;border-radius:var(--r-pill);background:var(--paper-300);overflow:hidden}
.eddy-progress__fill{height:100%;border-radius:var(--r-pill);background:var(--secondary)}
.eddy-progress--tier .eddy-progress__fill{background:var(--tier-redgold)}
.eddy-medal{display:inline-flex;align-items:center;justify-content:center;width:72px;height:72px;border-radius:var(--r-pill);border:2px solid var(--tier-bronze-ink);color:var(--tier-bronze-ink);font-weight:var(--fw-bold);font-size:var(--fs-md);flex:none}
.eddy-medal--filled{background:var(--tier-bronze);border-color:var(--tier-bronze);color:#fff}
.eddy-medal--locked{background:var(--paper-300);border-color:transparent;color:var(--text-subtle)}
.eddy-medal--jade{background:var(--tier-jade);border-color:var(--tier-jade);color:#fff}
.eddy-tierline{display:flex;align-items:center;gap:0}
.eddy-tierline__dot{width:16px;height:16px;border-radius:var(--r-pill);border:2px solid var(--border-strong);background:var(--surface-card);flex:none}
.eddy-tierline__dot.is-done{background:var(--tier-redgold);border-color:var(--tier-redgold)}
.eddy-tierline__dot.is-current{border-color:var(--tier-redgold)}
.eddy-tierline__bar{flex:1;height:2px;background:var(--border-default)}

/* ============ Учебные материалы и упражнения ============ */
.eddy-ex{border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-card);background:var(--surface-card);padding:var(--sp-7)}
.eddy-ex__no{font-size:var(--fs-2xs);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--text-subtle)}
.eddy-ex__q{margin-top:var(--sp-4);font-size:var(--fs-md);font-weight:var(--fw-semibold)}
.eddy-ex__hanzi{font-family:var(--font-hanzi);font-size:var(--fs-3xl);font-weight:500;line-height:1.2}
.eddy-ex__pinyin{font-size:var(--fs-sm);color:var(--secondary);letter-spacing:.02em}
.eddy-ex__opts{display:grid;gap:var(--sp-4);margin-top:var(--sp-6)}
.eddy-ex__opt{display:flex;align-items:center;gap:var(--sp-5);min-height:var(--tap-min);padding:var(--sp-4) var(--sp-6);border:var(--border-w) solid var(--border-default);border-radius:var(--r-md);background:var(--surface-card);font:inherit;font-size:var(--type-app-body-size);text-align:left;cursor:pointer;transition:var(--transition-control)}
.eddy-ex__opt:hover{border-color:var(--border-strong);background:var(--paper-100)}
.eddy-ex__opt.is-picked{border-color:var(--accent);background:var(--accent-soft)}
.eddy-ex__opt.is-right{border-color:var(--secondary);background:var(--secondary-soft);color:var(--jade-700)}
.eddy-ex__opt.is-wrong{border-color:var(--red-200);background:var(--red-50);color:var(--red-700)}
.eddy-ex__key{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:var(--r-sm);background:var(--paper-200);font-size:var(--fs-2xs);font-weight:var(--fw-bold);color:var(--ink-600);flex:none}

/* ============ Оболочка кабинетов: верхнее меню, без сайдбара ============
   Кабинет семьи и кабинет педагога устроены так в проекте; состав меню фиксирован. */
.eddy-cabnav{display:flex;align-items:center;gap:var(--sp-8);height:64px;padding:0 var(--sp-8);background:var(--surface-card);border-bottom:var(--border-w) solid var(--border-subtle);position:sticky;top:0;z-index:20}
.eddy-cabnav__list{display:flex;align-items:center;gap:var(--sp-2);margin-left:auto;overflow-x:auto}
.eddy-cabnav__list a{padding:var(--sp-4) var(--sp-6);border-radius:var(--r-pill);font-size:var(--type-app-body-size);font-weight:var(--fw-medium);color:var(--ink-600);white-space:nowrap;text-decoration:none}
.eddy-cabnav__list a:hover{background:var(--paper-200);color:var(--text-body);text-decoration:none}
.eddy-cabnav__list a.is-active{background:var(--accent);color:#fff;font-weight:var(--fw-semibold)}
.eddy-cabmain{max-width:1040px;margin:0 auto;padding:var(--sp-9) var(--sp-8) var(--sp-12);display:flex;flex-direction:column;gap:var(--sp-6)}
@media (max-width:1023px){.eddy-cabnav__list{display:none}.eddy-cabnav{height:56px;padding:0 var(--sp-5)}}
@media (max-width:767px){.eddy-cabmain{padding:var(--sp-6) var(--sp-5) var(--sp-11);gap:var(--sp-5)}}

/* Лента ближайших занятий — горизонтальная прокрутка, как в кабинете. */
.eddy-nextrow{display:flex;gap:var(--sp-5);overflow-x:auto;padding-bottom:var(--sp-3)}
.eddy-next{flex:0 0 232px;border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-card);padding:var(--sp-5) var(--sp-6);background:var(--surface-card)}
.eddy-next.is-next{border-color:var(--jade-200);box-shadow:inset 0 0 0 1px var(--jade-200)}
.eddy-next__wd{font-size:var(--fs-3xs);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--secondary)}
.eddy-next__when{margin-top:var(--sp-3);font-size:var(--fs-base);font-weight:var(--fw-bold);font-variant-numeric:tabular-nums}
.eddy-next__who{margin-top:var(--sp-3);font-size:var(--type-app-body-size);color:var(--ink-600);line-height:1.4}
.eddy-next__grp{margin-top:var(--sp-2);font-size:var(--fs-2xs);color:var(--text-muted)}

/* Настройки — решётка групп ссылок. */
.eddy-settings{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-5)}
.eddy-settings__group{border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-card);background:var(--surface-card);overflow:hidden}
.eddy-settings__title{padding:var(--sp-5) var(--sp-6);font-size:var(--fs-2xs);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--text-subtle);border-bottom:var(--rule)}
.eddy-settings__link{display:flex;align-items:center;gap:var(--sp-5);padding:var(--sp-5) var(--sp-6);font-size:var(--type-app-body-size);color:var(--ink-700);text-decoration:none;border-bottom:var(--border-w) solid var(--border-subtle)}
.eddy-settings__link:last-child{border-bottom:0}
.eddy-settings__link:hover{background:var(--paper-100);color:var(--accent-ink);text-decoration:none}
.eddy-settings__link svg{color:var(--text-subtle);flex:none}
@media (max-width:1279px){.eddy-settings{grid-template-columns:repeat(2,1fr)}}
@media (max-width:767px){.eddy-settings{grid-template-columns:1fr}}

/* Виджеты админпанели. */
.eddy-widgets{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-5)}
.eddy-widget{background:var(--surface-card);border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-card);padding:var(--sp-6) var(--sp-7)}
.eddy-widget__title{font-size:var(--type-app-section-size);font-weight:var(--fw-bold);letter-spacing:var(--ls-snug);margin-bottom:var(--sp-5)}
.eddy-widget__nums{display:flex;gap:var(--sp-8);align-items:flex-end}
.eddy-widget__num{font-size:var(--fs-xl);font-weight:var(--fw-bold);font-variant-numeric:tabular-nums;line-height:1.1}
.eddy-widget__cap{margin-top:var(--sp-3);font-size:var(--fs-3xs);font-weight:var(--fw-semibold);letter-spacing:var(--ls-wide);text-transform:uppercase;color:var(--text-subtle)}
.eddy-bar{height:6px;border-radius:var(--r-pill);background:var(--paper-300);overflow:hidden;margin-top:var(--sp-3)}
.eddy-bar__fill{height:100%;background:var(--secondary);border-radius:var(--r-pill)}
@media (max-width:1279px){.eddy-widgets{grid-template-columns:repeat(2,1fr)}}
@media (max-width:767px){.eddy-widgets{grid-template-columns:1fr}}

/* Четыре блока денег на карточке ученика: абонементы · платежи · скидки · договоры */
.eddy-money4{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-5)}
@media (max-width:1279px){.eddy-money4{grid-template-columns:repeat(2,1fr)}}
@media (max-width:767px){.eddy-money4{grid-template-columns:1fr}}

/* ============ Награды и опыт (XP) ============
   Одна геометрия на все ранги: круглый жетон, внутри знак, снизу подпись.
   Ценность читается тремя способами сразу — цвет ранга, число колец и число
   звёзд. Бронза плоская и тусклая, изумруд — с двойным кольцом и сиянием.
   Так «10 уроков подряд» видно отличается от «HSK 4 сдан». */
.eddy-award{display:flex;flex-direction:column;align-items:center;gap:var(--sp-4);width:112px;text-align:center;flex:none}
.eddy-award__disc{position:relative;width:72px;height:72px;border-radius:var(--r-pill);display:grid;place-items:center;color:#fff;flex:none}
.eddy-award--lg .eddy-award__disc{width:104px;height:104px}
.eddy-award--sm{width:84px}
.eddy-award--sm .eddy-award__disc{width:48px;height:48px}
.eddy-award__disc svg{position:relative;z-index:1;width:46%;height:46%}
.eddy-award--lg .eddy-award__disc svg{width:44%;height:44%}
.eddy-award__ring{position:absolute;inset:-5px;border-radius:var(--r-pill);border:2px solid currentColor;opacity:.35}
.eddy-award__ring--2{inset:-10px;opacity:.18}
.eddy-award__glow{position:absolute;inset:-14px;border-radius:var(--r-pill);background:currentColor;opacity:.10}
.eddy-award__label{font-size:var(--fs-2xs);font-weight:var(--fw-semibold);line-height:1.3;color:var(--text-body)}
.eddy-award__tier{font-size:var(--fs-3xs);color:var(--text-subtle)}
.eddy-award__stars{display:flex;gap:2px;justify-content:center;color:var(--tier-gold)}
.eddy-award__stars svg{width:10px;height:10px}
.eddy-award--locked .eddy-award__disc{background:var(--paper-300)!important;color:var(--text-subtle)!important;box-shadow:none!important}
.eddy-award--locked .eddy-award__ring,.eddy-award--locked .eddy-award__glow{display:none}
.eddy-award--locked .eddy-award__label{color:var(--text-subtle)}
.eddy-award--locked .eddy-award__stars{color:var(--ink-200)}
.eddy-award--bronze .eddy-award__disc{background:var(--tier-bronze);color:var(--tier-bronze-ink)}
.eddy-award--silver .eddy-award__disc{background:var(--tier-silver);color:var(--tier-silver-ink)}
.eddy-award--gold .eddy-award__disc{background:var(--tier-gold);color:var(--tier-gold-ink)}
.eddy-award--redgold .eddy-award__disc{background:var(--tier-redgold);color:var(--tier-redgold-ink)}
.eddy-award--platinum .eddy-award__disc{background:var(--tier-platinum);color:var(--tier-platinum-ink)}
.eddy-award--diamond .eddy-award__disc{background:var(--tier-diamond);color:var(--tier-diamond-ink)}
.eddy-award--emerald .eddy-award__disc{background:var(--tier-emerald);color:var(--tier-emerald-ink)}
.eddy-award--brand .eddy-award__disc{background:var(--accent);color:var(--accent-pressed)}
.eddy-award__disc--shine::after{content:"";position:absolute;inset:0;border-radius:var(--r-pill);background:linear-gradient(150deg,rgba(255,255,255,.45),rgba(255,255,255,0) 55%)}

/* Опыт: полоса уровня и плашка «+XP» */
.eddy-xp{display:flex;align-items:center;gap:var(--sp-5)}
.eddy-xp__lvl{display:grid;place-items:center;width:40px;height:40px;border-radius:var(--r-pill);background:var(--accent);color:#fff;font-weight:var(--fw-bold);font-size:var(--fs-sm);flex:none}
.eddy-xp__body{flex:1;min-width:0}
.eddy-xp__row{display:flex;font-size:var(--fs-2xs);color:var(--text-muted);margin-bottom:var(--sp-3)}
.eddy-xp__row b{color:var(--text-body);font-variant-numeric:tabular-nums}
.eddy-xp__bar{height:8px;border-radius:var(--r-pill);background:var(--paper-300);overflow:hidden}
.eddy-xp__fill{height:100%;border-radius:var(--r-pill);background:var(--tier-gold)}
.eddy-xp-chip{display:inline-flex;align-items:center;gap:4px;padding:2px var(--sp-4);border-radius:var(--r-pill);background:var(--xp-bg);color:var(--xp);font-size:var(--fs-2xs);font-weight:var(--fw-bold)}
.eddy-award-grid{display:flex;flex-wrap:wrap;gap:var(--sp-6)}

/* ============ Всплывающая карточка урока в расписании ============
   Нажатие на урок притеняет сетку и открывает карточку поверх: тип, время,
   аудитория, педагог, предмет, группа и список учеников с остатком уроков.
   Остаток красный при нуле, жёлтый при одном — это главное, зачем её открывают. */
.eddy-pop-scrim{position:fixed;inset:0;background:rgba(251,250,248,.72);backdrop-filter:blur(2px);z-index:40}
.eddy-pop{position:absolute;z-index:41;width:360px;max-width:calc(100vw - 32px);background:var(--surface-card);border:var(--border-w) solid var(--border-default);border-radius:var(--r-card);box-shadow:var(--sh-lg);overflow:hidden}
.eddy-pop__head{display:flex;align-items:center;gap:var(--sp-4);padding:var(--sp-5) var(--sp-6);border-bottom:var(--rule);font-size:var(--type-app-body-size);font-weight:var(--fw-semibold)}
.eddy-pop__body{padding:var(--sp-5) var(--sp-6);max-height:52vh;overflow-y:auto}
.eddy-pop__foot{display:flex;gap:var(--sp-4);padding:var(--sp-5) var(--sp-6);border-top:var(--rule);background:var(--paper-100)}
.eddy-pop__students{list-style:none;margin:var(--sp-5) 0 0;padding:0;display:grid;gap:2px;counter-reset:s}
.eddy-pop__students li{display:flex;align-items:center;gap:var(--sp-4);min-height:32px;font-size:var(--type-app-body-size)}
.eddy-pop__students li::before{counter-increment:s;content:counter(s) ".";width:20px;text-align:right;color:var(--text-subtle);font-size:var(--fs-2xs);flex:none}
.eddy-pop__left{margin-left:auto;font-size:var(--fs-2xs);font-variant-numeric:tabular-nums;color:var(--text-muted)}
.eddy-pop__left--zero{color:var(--status-danger);font-weight:var(--fw-semibold)}
.eddy-pop__left--low{color:var(--yellow-600);font-weight:var(--fw-semibold)}
@media (max-width:767px){.eddy-pop{position:fixed;left:8px;right:8px;bottom:8px;width:auto}}

/* ============ Экран правки записи (было: форма jazzmin) ============
   Две колонки полей, разделы с подписями, действия — залипающей панелью справа,
   на телефоне — снизу. Обязательное помечено красной звёздочкой, подсказка под полем. */
.eddy-editor{display:grid;grid-template-columns:minmax(0,1fr) 260px;gap:var(--sp-8);align-items:start}
.eddy-editor__side{position:sticky;top:calc(var(--topbar-h) + var(--sp-6));display:grid;gap:var(--sp-4)}
.eddy-fieldset{border:0;margin:0 0 var(--sp-6);padding:0}
.eddy-fieldset__title{font-size:var(--fs-2xs);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--text-subtle);padding-bottom:var(--sp-4);border-bottom:var(--rule);margin-bottom:var(--sp-6)}
.eddy-fieldgrid{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-6) var(--sp-8)}
.eddy-fieldgrid--1{grid-template-columns:1fr}
.eddy-field-actions{display:flex;gap:var(--sp-3);align-items:flex-end}
.eddy-field-actions .eddy-iconbtn{margin-bottom:1px}
@media (max-width:1023px){.eddy-editor{grid-template-columns:1fr}.eddy-editor__side{position:static;grid-auto-flow:column}}
@media (max-width:767px){.eddy-fieldgrid{grid-template-columns:1fr}.eddy-editor__side{grid-auto-flow:row}}


/* ── Выпадающее меню: «Действия», «Отчёты», «Другое», «Фильтр» ─────────────
   В CRM это главный способ добраться до массовых операций и отчётов.
   Разделители между строками — как в продукте; недоступные пункты не
   исчезают, а гаснут: сотрудник видит, что операция существует. */
.eddy-menu{position:relative;display:inline-block}
.eddy-menu__pop{position:absolute;top:calc(100% + 6px);left:0;z-index:40;min-width:232px;max-height:min(62vh,420px);overflow-y:auto;padding:var(--sp-2) 0;background:var(--surface-card);border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-card);box-shadow:var(--sh-lg)}
.eddy-menu__pop--right{left:auto;right:0}
.eddy-menu__sec{padding:var(--sp-5) var(--sp-6) var(--sp-2);font-size:var(--fs-3xs);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--text-subtle)}
.eddy-menu__item{display:flex;align-items:center;gap:var(--sp-4);width:100%;padding:var(--sp-5) var(--sp-6);border:0;border-bottom:var(--border-w) solid var(--border-subtle);background:none;font:inherit;font-size:var(--type-app-body-size);color:var(--text-body);text-align:left;cursor:pointer}
.eddy-menu__item:last-child{border-bottom:0}
.eddy-menu__item:hover{background:var(--paper-100);text-decoration:none;color:var(--text-body)}
.eddy-menu__item:focus-visible{outline:none;background:var(--paper-100);box-shadow:inset 0 0 0 2px var(--accent-soft)}
.eddy-menu__item[disabled],.eddy-menu__item.is-disabled{color:var(--state-disabled-text);cursor:not-allowed;background:none}
.eddy-menu__item--danger{color:var(--status-danger)}
.eddy-menu__item svg{width:16px;height:16px;flex:none;opacity:.75}
.eddy-menu__hint{margin-left:auto;font-size:var(--fs-3xs);color:var(--text-subtle)}
@media (max-width:767px){.eddy-menu__pop{position:fixed;left:0;right:0;bottom:0;top:auto;min-width:0;max-height:70vh;border-radius:var(--r-xl) var(--r-xl) 0 0;box-shadow:var(--sh-modal)}.eddy-menu__item{padding:var(--sp-6);min-height:var(--tap-min)}}

/* ── Колокольчик уведомлений ───────────────────────────────────────────────
   В продукте строки помечены эмодзи (⚠, 👥). Здесь вместо них — знаки
   системы: треугольник для предупреждения, две фигуры для дубля. */
.eddy-bell{position:relative;display:inline-block}
.eddy-bell__badge{position:absolute;top:-5px;right:-5px;display:flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border-radius:var(--r-pill);background:var(--status-danger);color:#fff;font-size:11px;font-weight:var(--fw-bold);line-height:1;font-variant-numeric:tabular-nums;box-shadow:0 0 0 2px var(--surface-card)}
.eddy-bell__pop{position:absolute;top:calc(100% + 8px);right:0;z-index:40;width:340px;max-height:min(64vh,440px);overflow-y:auto;background:var(--surface-card);border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-card);box-shadow:var(--sh-lg)}
.eddy-bell__head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);padding:var(--sp-5) var(--sp-6);border-bottom:var(--border-w) solid var(--border-default);font-size:var(--fs-3xs);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--text-subtle)}
.eddy-bell__item{display:flex;gap:var(--sp-4);padding:var(--sp-5) var(--sp-6);border-bottom:var(--border-w) solid var(--border-subtle);font-size:var(--type-app-body-size);line-height:var(--lh-normal);color:var(--text-body);text-align:left;width:100%;border-left:0;border-right:0;border-top:0;background:none;font-family:inherit;cursor:pointer}
.eddy-bell__item:hover{background:var(--paper-100);text-decoration:none}
.eddy-bell__item:last-of-type{border-bottom:0}
.eddy-bell__mark{flex:none;display:flex;width:18px;height:18px;margin-top:1px}
.eddy-bell__mark--warn{color:var(--yellow-600)}
.eddy-bell__mark--dup{color:var(--ink-500)}
.eddy-bell__foot{position:sticky;bottom:0;padding:var(--sp-5) var(--sp-6);background:var(--paper-100);border-top:var(--border-w) solid var(--border-subtle);font-size:var(--type-app-meta-size)}
.eddy-bell__empty{padding:var(--sp-8) var(--sp-6);text-align:center;font-size:var(--type-app-body-size);color:var(--text-muted)}
@media (max-width:767px){.eddy-bell__pop{position:fixed;left:var(--sp-4);right:var(--sp-4);width:auto;top:auto;bottom:var(--sp-4);max-height:72vh}}

/* ── Фильтрация данных: сетка полей в модальном окне ───────────────────── */
.eddy-filter{display:grid;gap:var(--sp-6)}
.eddy-filter__pair{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4)}
.eddy-filter__count{font-size:var(--type-app-meta-size);color:var(--text-muted);margin-right:auto}


/* ── Без JS: меню и окна средствами HTML ───────────────────────────────────
   <details class="eddy-menu"> — меню тулбара, <a href="#id"> → :target — окно.
   Серверный HTML из Django, сборки нет: это единственный честный способ. */
.eddy-menu>summary{list-style:none;cursor:pointer}
.eddy-menu>summary::-webkit-details-marker,.eddy-bell>summary::-webkit-details-marker{display:none}
.eddy-menu>summary::marker,.eddy-bell>summary::marker{content:""}
.eddy-menu[open]>summary{background:var(--paper-200)}
.eddy-bell>summary{list-style:none;cursor:pointer}
.eddy-modal__scrim--target{display:none}
.eddy-modal__scrim--target:target{display:flex}

/* ── Подвал списка: сколько показано и сколько строк на странице ───────── */
.eddy-pager{display:flex;align-items:center;gap:var(--sp-5);flex-wrap:wrap;margin-top:var(--sp-6);font-size:var(--type-app-meta-size);color:var(--text-muted)}
.eddy-pager__count{font-variant-numeric:tabular-nums}
.eddy-pager__size{display:flex;align-items:center;gap:var(--sp-4);margin-left:auto}
.eddy-pager__size .eddy-select select{height:var(--control-h-sm);font-size:var(--fs-xs)}
.eddy-pager .eddy-btn[aria-disabled="true"]{pointer-events:none;color:var(--state-disabled-text)}

/* ── Пустое состояние: строка о том, чего нет. Без картинок и без «Ой!» ── */
.eddy-empty{display:flex;align-items:center;gap:var(--sp-5);flex-wrap:wrap;padding:var(--sp-7) var(--sp-6);color:var(--text-muted);font-size:var(--type-app-body-size)}
.eddy-empty__text{margin:0}
.eddy-empty--block{justify-content:center;text-align:center;border:var(--border-w) dashed var(--border-default);border-radius:var(--r-card);background:var(--paper-100)}

/* ── Полоса сообщения над формой ───────────────────────────────────────── */
.eddy-alert{padding:var(--sp-5) var(--sp-6);border-radius:var(--r-md);font-size:var(--type-app-body-size);line-height:var(--lh-normal)}
.eddy-alert--danger{background:var(--red-50,#FDECEA);border:var(--border-w) solid var(--status-danger);color:var(--red-700,#A32620)}
.eddy-alert--warn{background:var(--yellow-50);border:var(--border-w) solid var(--yellow-100);color:var(--ink-700)}
.eddy-alert--info{background:var(--paper-100);border:var(--border-w) solid var(--border-default);color:var(--ink-700)}

/* ── Форма записи: разделы, два столбца, залипающая панель действий ────── */
.eddy-form{display:grid;gap:var(--sp-8)}
.eddy-form__section{padding:var(--sp-7);background:var(--surface-card);border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-card)}
.eddy-form__legend{margin:0 0 var(--sp-2);font-size:var(--fs-3xs);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--text-subtle)}
.eddy-form__hint{margin:0 0 var(--sp-6);font-size:var(--type-app-meta-size);color:var(--text-muted)}
.eddy-form__grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-6)}
.eddy-field--wide{grid-column:1/-1}
@media (max-width:767px){.eddy-form__grid{grid-template-columns:1fr}}
.eddy-form__actions{position:sticky;bottom:0;display:flex;align-items:center;gap:var(--sp-4);flex-wrap:wrap;padding:var(--sp-5) var(--sp-6);background:var(--surface-card);border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-card);box-shadow:var(--sh-md)}
.eddy-field.is-invalid .eddy-input,.eddy-field.is-invalid select{border-color:var(--status-danger)}

/* ── Обёртка таблицы: горизонтальная прокрутка. Залипание колонок живёт в table.css ── */
.eddy-tablewrap{overflow-x:auto;-webkit-overflow-scrolling:touch;border:var(--border-w) solid var(--border-subtle);border-radius:var(--r-card);background:var(--surface-card)}
.eddy-tablewrap .eddy-table{border:0;border-radius:0}
.eddy-modal__lead{margin:0 0 var(--sp-6);font-size:var(--fs-sm);line-height:var(--lh-normal);color:var(--ink-700)}
