/* Пара · app.css — компоненты каркаса. Портирован из design-drafts/assets/app.css
   (журнал html-дорожки 2026-11-07: бриф «спокойно видеть главное» приоритетнее
   прежней палитры docs/03). Единственный источник цветов — tokens.css (AGENTS §5.6);
   пути шрифтов адаптированы под /static/fonts/ (самохостинг, без CDN — AGENTS).
   Проверка контраста: python3 -I tools/contrast_check.py → 0 FAIL.
   Правки по ревью каркаса (07.11): shimmer-скелетон, инверсный тост и offset
   фокуса 2px — по 03 §2.8/§6.4; кнопка «Повторить» офлайн-баннера — 03 §5.4.
   Расхождения с 03 §2 (палитра/размеры) — решение Р-16 в docs/decisions.md. */
@font-face{font-family:Inter;src:url(/static/fonts/inter-latin.woff2) format('woff2');font-weight:100 900;font-display:swap}
@font-face{font-family:Inter;src:url(/static/fonts/inter-cyrillic.woff2) format('woff2');font-weight:100 900;font-display:swap;unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
*{box-sizing:border-box}html{scroll-padding-top:6rem}body{margin:0;background:var(--bg);color:var(--text);font:1rem/1.55 var(--font-body);font-feature-settings:'tnum';overflow-wrap:anywhere}a{color:var(--primary);text-underline-offset:4px}button,input,select,textarea{font:inherit}a,button,summary{touch-action:manipulation}a,button,summary,input,select,textarea{ -webkit-tap-highlight-color:var(--clear)}button{cursor:pointer}a,button,summary{min-width:44px;min-height:44px}a{display:inline-flex;align-items:center}button{border:0}h1,h2,h3,p{margin:0}h1,h2,h3{font-family:var(--font-heading);line-height:1.25}h1{font-size:1.75rem;letter-spacing:-.04em;font-weight:600}h2{font-size:1.25rem;letter-spacing:-.025em;font-weight:600}h3{font-size:1rem;font-weight:600}p+p{margin-top:.5rem}small,.caption{font-size:.875rem;line-height:1.5;color:var(--text-2)}.muted{color:var(--text-2)}.eyebrow,.overline{font-size:.75rem;letter-spacing:.09em;text-transform:uppercase;font-weight:600;color:var(--text-2)}.small{font-size:.875rem}.serif{font-family:var(--font-greeting);font-weight:400;letter-spacing:-.045em}.red{color:var(--danger-text)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.skip{position:fixed;top:0;left:1rem;z-index:100;padding:1rem;background:var(--surface);transform:translateY(-150%)}.skip:focus{transform:none}:focus-visible{outline:2px solid var(--primary);outline-offset:2px;border-radius:4px}
.site-header{background:var(--surface);border-bottom:1px solid var(--border);position:sticky;top:0;z-index:20}.header-inner{max-width:1200px;margin:auto;min-height:72px;padding:.75rem 1rem;display:flex;align-items:center;justify-content:space-between;gap:1rem}.brand{font-size:1.75rem;letter-spacing:-.07em;line-height:1;font-weight:650;color:var(--text);text-decoration:none;gap:.65rem;white-space:nowrap}.brand-symbol{display:inline-flex;gap:3px;align-items:center;width:22px;height:25px}.brand-symbol:before,.brand-symbol:after{content:'';width:9px;height:23px;border:2px solid var(--primary);border-radius:5px}.brand-symbol:after{height:17px;align-self:flex-end}.header-actions{display:flex;align-items:center;gap:.5rem}.header-date{display:none}.icon{width:20px;height:20px;flex:none;fill:none;stroke:currentColor;stroke-width:1.65;stroke-linecap:round;stroke-linejoin:round}.icon-button{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;border:1px solid var(--border);border-radius:var(--r-full);background:var(--surface);color:var(--text);text-decoration:none;position:relative}.icon-button:hover{background:var(--surface-2)}.notification-count{position:absolute;right:-2px;top:-4px;min-width:18px;min-height:18px;padding:0 4px;font-size:.75rem;line-height:18px;text-align:center;border-radius:var(--r-full);background:var(--primary);color:var(--on-primary)}.avatar{display:flex;align-items:center;justify-content:center;width:44px;height:44px;flex:none;border-radius:var(--r-full);background:var(--primary-soft-bg);color:var(--primary-soft-text);font-weight:600;font-size:.875rem;text-decoration:none}.avatar.large{width:64px;height:64px;font-size:1.25rem}.primary-nav{position:fixed;bottom:0;left:0;right:0;z-index:30;display:flex;background:var(--surface);border-top:1px solid var(--border);padding:6px 0 calc(6px + env(safe-area-inset-bottom));justify-content:space-around}/* подпись таба — одной строкой (nowrap против побуквенного «Расписани е»
   от глобального overflow-wrap:anywhere), кегль .625rem + tracking -.01em —
   самая длинная «Успеваемость» (~70px при 10px Inter) помещается в колонку
   20% при 360px (полоса без боковых паддингов = 72px на таб); ellipsis —
   страховка для окон <360px; тап-зона не тронута (min-height:52px +
   паддинг полосы 6px = ~64px, ширина 20%) */
.nav-link{display:flex;align-items:center;flex-direction:column;justify-content:center;gap:4px;color:var(--text-2);text-decoration:none;font-size:.625rem;font-weight:500;letter-spacing:-.01em;min-height:52px;width:20%;padding:4px 0;white-space:nowrap}
.nav-link span{max-width:100%;overflow:hidden;text-overflow:ellipsis}.nav-link[aria-current]{color:var(--primary);font-weight:600}.nav-link[aria-current] .icon{stroke-width:2.2}.staff-nav{display:flex;gap:1rem;flex-wrap:wrap}.staff-nav a{font-size:.875rem;text-decoration:none}.staff-label{display:none}
.shell{max-width:1200px;padding:0 1rem 6rem;margin:auto}.page-heading{padding:2rem 0 1.5rem;display:flex;justify-content:space-between;gap:1rem;align-items:center}.page-heading p{margin-top:.6rem;color:var(--text-2);font-size:.875rem}.page-heading .eyebrow{margin:0 0 .75rem}.page-heading .back{margin-bottom:.5rem}.page-heading .serif{font-size:2rem}.content-narrow{max-width:720px}.content-form{max-width:600px;margin:auto}.back{gap:.25rem;font-size:.875rem;text-decoration:none}.section{margin-top:2rem}.section-title{display:flex;align-items:center;justify-content:space-between;gap:.75rem;min-height:44px;margin-bottom:.75rem}.section-title h2{font-size:1.125rem}.section-title a{font-size:.875rem;text-decoration:none;gap:.35rem;flex-shrink:0}.surface{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);padding:1.25rem}.stack{display:grid;gap:.75rem}.stack-lg{display:grid;gap:1.5rem}.row{display:flex;align-items:center;gap:.75rem;justify-content:space-between}.row.wrap{flex-wrap:wrap}.row>*{min-width:0}.flow>*+*{margin-top:1rem}.button{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;padding:.7rem 1.1rem;min-height:48px;border:1px solid var(--control-border);border-radius:var(--r-md);background:var(--surface);color:var(--primary);font-size:.875rem;font-weight:600;line-height:1.4;text-decoration:none;text-align:center}.button:hover{background:var(--surface-2)}.button:active{transform:translateY(1px)}.button.primary{color:var(--on-primary);background:var(--primary);border-color:var(--primary)}.button.primary:hover{background:var(--primary-hover)}.button.primary:active{background:var(--primary-pressed)}.button.ghost{border-color:var(--clear);background:var(--clear);padding-inline:.5rem}.button.danger-button{color:var(--danger-text);background:var(--danger-bg);border-color:var(--danger-text)}.button:disabled{background:var(--surface-2);color:var(--text-2);border-color:var(--border);cursor:not-allowed;transform:none}.full{width:100%}.actions{display:flex;gap:.75rem;flex-wrap:wrap}.actions>*{flex:1}.badge{display:inline-flex;align-items:center;gap:.3rem;font-size:.75rem;font-weight:500;line-height:1.4;padding:.3rem .65rem;min-height:24px;border-radius:var(--r-full);background:var(--surface-2);color:var(--text-2);max-width:100%;flex-shrink:0}.badge.success,.badge.info{background:var(--primary-soft-bg);color:var(--primary-soft-text)}.badge.danger{background:var(--danger-bg);color:var(--danger-text)}.badge.outline{background:var(--surface);border:1px solid var(--border)}.notice{padding:1rem;border:1px solid var(--border);border-radius:var(--r-md);background:var(--surface-2);color:var(--text-2);font-size:.875rem;line-height:1.5}.notice.danger{background:var(--danger-bg);border-color:var(--danger-text);color:var(--danger-text)}.notice.success{color:var(--primary-soft-text)}.chips,.segments{display:flex;gap:.5rem;flex-wrap:wrap}.segments{padding:4px;background:var(--surface-2);border-radius:var(--r-md);width:fit-content}.segments>a,.segments>button{display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:.5rem 1rem;background:var(--clear);color:var(--text-2);border-radius:var(--r-sm);text-decoration:none;font-size:.875rem;font-weight:500}.segments [aria-current],.segments [aria-pressed=true]{background:var(--surface);color:var(--text);box-shadow:var(--e1)}.chip{display:inline-flex;align-items:center;justify-content:center;padding:.5rem .9rem;min-height:44px;border:1px solid var(--border);border-radius:var(--r-full);background:var(--surface);color:var(--text-2);font-size:.875rem;text-decoration:none}.chip[aria-pressed=true],.chip[aria-current]{color:var(--primary-soft-text);border-color:var(--primary);background:var(--primary-soft-bg)}
.greeting-note{display:none}.dashboard-grid{display:grid;gap:2rem}.next-class{padding:1.5rem;border:1px solid var(--border);border-radius:var(--r-xl);background:var(--surface)}.next-meta{display:flex;gap:.5rem;align-items:center;font-size:.875rem;color:var(--primary);font-weight:500}.next-time{font-size:2rem;font-weight:500;line-height:1.2;letter-spacing:-.05em;margin:1.5rem 0 .6rem}.next-class h2{font-size:1.375rem;line-height:1.35}.next-location{display:flex;justify-content:space-between;gap:1rem;align-items:center;margin:1.5rem 0;border-block:1px solid var(--border);padding:1rem 0}.next-location strong{display:block;font-size:1.375rem;line-height:1.3;font-weight:600}.next-location a{text-decoration:none}.teacher-line{display:flex;gap:.75rem;align-items:center;color:var(--text);text-decoration:none;font-size:.875rem}.teacher-line .avatar{width:36px;height:36px;font-size:.75rem}.schedule-list{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);padding:0 1rem}.lesson{display:grid;grid-template-columns:3rem minmax(0,1fr) auto;gap:.7rem;padding:1.1rem 0;border-bottom:1px solid var(--border);align-items:start}.lesson:last-child{border-bottom:0}.lesson-time strong{font-size:1rem;font-weight:600;display:block}.lesson-time span{display:block;font-size:.75rem;color:var(--text-2);margin-top:.25rem}.lesson-subject{font-weight:600;font-size:.9375rem;line-height:1.45}.lesson-detail{font-size:.875rem;color:var(--text-2);margin-top:.3rem}.lesson-teacher{font-size:.875rem;text-decoration:none;color:var(--text-2)}.lesson-room{display:flex;flex-direction:column;align-items:flex-end;text-decoration:none;min-width:44px;font-size:1.0625rem;font-weight:600}.lesson-room small{font-size:.75rem;font-weight:400;white-space:nowrap}.change-block{position:relative;border-left:2px solid var(--danger-text);background:var(--danger-bg);border-radius:0 var(--r-md) var(--r-md) 0;padding:1rem 1.125rem;color:var(--text);font-size:.875rem}.change-block h3{font-size:1rem;margin-bottom:.5rem}.change-label{display:block;font-size:.875rem;color:var(--danger-text);font-weight:500;margin-bottom:.25rem}.change-route{display:flex;align-items:center;flex-wrap:wrap;gap:.4rem}.change-route s{color:var(--text-2)}.change-route a{font-weight:600;color:var(--danger-text);font-size:1rem}.change-block .caption{margin-top:.3rem}.change-block .change-detail{font-size:.875rem;color:var(--danger-text);margin-top:.5rem}.deadline-list{list-style:none;margin:0;padding:0}.deadline-list li{border-bottom:1px solid var(--border);padding:1rem 0}.deadline-list li:last-child{border-bottom:0}.deadline-list a{font-weight:500;color:var(--text);text-decoration:none}.deadline-time{font-size:.875rem;color:var(--danger-text);margin-top:.25rem}.deadline-time.calm{color:var(--text-2)}.compact-app{padding:1rem 0;border-bottom:1px solid var(--border)}.compact-app:last-child{border-bottom:0}.compact-app>a{font-size:.9375rem;font-weight:500;text-decoration:none;color:var(--text)}.mini-progress{display:flex;gap:4px;margin:.75rem 0 .5rem}.mini-progress span{height:3px;border-radius:var(--r-full);background:var(--border);flex:1}.mini-progress .done{background:var(--primary)}.news-row{border-top:1px solid var(--border);padding:1rem 0}.news-row a{font-weight:500;color:var(--text);text-decoration:none}.service-grid{display:grid;grid-template-columns:1fr;gap:.75rem}.service-link{display:flex;gap:1rem;padding:1rem;border:1px solid var(--border);border-radius:var(--r-lg);align-items:center;color:var(--text);text-decoration:none}.service-link>.icon{color:var(--primary);width:24px;height:24px}.service-link strong{font-size:.9375rem;display:block}.service-link p{font-size:.875rem;color:var(--text-2)}.calendar-toolbar{display:flex;align-items:end;justify-content:space-between;gap:1rem;flex-wrap:wrap;margin-bottom:1.25rem}.week-strip{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:3px;margin:1.25rem 0}.day-pill{display:flex;flex-direction:column;justify-content:center;align-items:center;border:1px solid var(--clear);background:var(--clear);color:var(--text-2);border-radius:var(--r-md);font-size:.75rem;text-decoration:none;min-height:64px;min-width:0}.day-pill strong{font-size:1rem;font-weight:500}.day-pill[aria-current]{background:var(--primary);color:var(--on-primary)}.day-pill .today-dot{width:4px;height:4px;border-radius:var(--r-full);background:var(--primary);margin-top:4px}.day-pill[aria-current] .today-dot{background:var(--on-primary)}.day-group{margin:1.5rem 0}.day-group h2{font-size:.9375rem;margin-bottom:.75rem}.empty{padding:2rem 1.25rem;text-align:center}.empty .empty-icon{display:inline-flex;align-items:center;justify-content:center;width:56px;height:56px;border-radius:var(--r-full);background:var(--surface-2);color:var(--primary);margin-bottom:1.25rem}.empty h2{font-size:1.25rem;margin-bottom:.75rem}.empty p{color:var(--text-2);font-size:.875rem;margin-bottom:1.25rem;max-width:34rem;margin-inline:auto}.empty .button{margin-top:.5rem}.metric{font-size:2.5rem;letter-spacing:-.05em;font-weight:500;line-height:1.2}.study-summary{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:1.5rem 0;border-block:1px solid var(--border)}.discipline-row{display:block;color:var(--text);text-decoration:none;padding:1.25rem 0;border-bottom:1px solid var(--border)}.discipline-row h3{max-width:80%}.progress{height:5px;border-radius:var(--r-full);background:var(--border);margin:.75rem 0}.progress:before{content:'';display:block;width:var(--value,78%);height:100%;border-radius:inherit;background:var(--primary)}.progress.risk:before{background:var(--danger-text)}.p30{--value:30%}.p60{--value:60%}.p78{--value:78%}.p83{--value:83%}.p92{--value:92%}.p100{--value:100%}.list-row{display:flex;align-items:center;justify-content:space-between;gap:1rem;min-height:64px;padding:1rem 0;border-bottom:1px solid var(--border);text-decoration:none;color:var(--text);width:100%}.list-row:last-child{border:0}.list-row p{color:var(--text-2);font-size:.875rem;margin-top:.25rem}.list-row strong{font-weight:500}.list-row .price{font-weight:600;white-space:nowrap}.document-type{display:flex;align-items:center;gap:1rem;padding:1.25rem;border:1px solid var(--border);border-radius:var(--r-lg);color:var(--text);text-decoration:none}.document-type:hover{border-color:var(--primary);background:var(--surface)}.document-type>.icon:first-child{color:var(--primary)}.document-type>div{flex:1}.document-type p{font-size:.875rem;color:var(--text-2);margin-top:.25rem}.timeline{list-style:none;margin:1.5rem 0;padding:0 0 0 .4rem}.timeline li{position:relative;border-left:1px solid var(--border);padding:0 0 1.5rem 1.5rem}.timeline li:last-child{padding-bottom:0;border-color:var(--clear)}.timeline li:before{content:'';position:absolute;width:10px;height:10px;background:var(--surface);border:2px solid var(--control-border);border-radius:var(--r-full);left:-5.5px;top:5px}.timeline li.done:before{background:var(--primary);border-color:var(--primary)}.timeline li.current:before{background:var(--primary);border-color:var(--primary);box-shadow:0 0 0 4px var(--primary-soft-bg)}.timeline p{font-size:.875rem;color:var(--text-2);margin-top:.3rem}.timeline .future{color:var(--text-2)}.form-section{margin:1.5rem 0}label{display:block;font-size:.875rem;color:var(--text);margin-bottom:.4rem}input:not([type=checkbox]):not([type=radio]),select,textarea{width:100%;min-width:0;min-height:48px;padding:.75rem .875rem;border:1px solid var(--control-border);background:var(--surface);color:var(--text);border-radius:var(--r-md);font-size:1rem}input::placeholder,textarea::placeholder{color:var(--text-2)}input[aria-invalid=true],textarea[aria-invalid=true]{border-color:var(--danger-text)}textarea{resize:vertical}fieldset{border:0;padding:0;margin:1.5rem 0;min-width:0}legend{font-size:.875rem;font-weight:500;margin-bottom:.75rem}.field{margin:1rem 0}.field .caption{display:block;margin-top:.4rem}.field-error{font-size:.875rem;color:var(--danger-text);margin-top:.4rem}.option{display:flex;align-items:center;gap:.75rem;padding:.75rem 1rem;min-height:48px;border:1px solid var(--control-border);border-radius:var(--r-md);background:var(--surface);margin:.5rem 0;color:var(--text)}.option:has(input:checked){border-color:var(--primary);background:var(--primary-soft-bg)}input[type=radio],input[type=checkbox]{width:22px;height:22px;flex:none;accent-color:var(--primary)}.password-wrap{position:relative}.password-wrap input{padding-right:3.5rem!important}.password-wrap button{position:absolute;right:2px;top:2px;border:0;background:var(--clear)}.login-layout{max-width:440px;margin:auto}.login-intro{padding:2rem 0 1rem}.login-intro .serif{font-size:2.5rem;line-height:1.15;margin-bottom:1rem}.login-roles{display:grid;gap:.5rem}.role-button{display:flex;align-items:center;gap:.75rem;background:var(--surface);color:var(--text);border:1px solid var(--border);border-radius:var(--r-md);padding:.75rem 1rem;text-align:left;min-height:64px}.role-button[aria-pressed=true]{background:var(--primary-soft-bg);border-color:var(--primary)}.role-button>div{flex:1}.role-button strong{font-size:.875rem;font-weight:500;display:block}.role-button span{font-size:.75rem;color:var(--text-2)}.room-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.6rem}.room-slot{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.2rem;min-height:76px;padding:.75rem;border:1px solid var(--control-border);border-radius:var(--r-md);background:var(--surface);color:var(--primary);font-size:.875rem}.room-slot span{font-size:.75rem;color:var(--text-2)}.room-slot[aria-pressed=true],.room-slot.mine{background:var(--primary-soft-bg);border:2px solid var(--primary);color:var(--primary-soft-text)}.room-slot:disabled{background:var(--bg);color:var(--text-2);border-color:var(--border);cursor:not-allowed}.booking-summary{padding:1.25rem;border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);margin-top:1.5rem}.booking-summary h3{font-size:1.125rem}.notification{border-bottom:1px solid var(--border);padding:1.25rem 0;display:grid;grid-template-columns:24px 1fr;gap:.75rem}.notification>.icon{margin-top:.3rem;color:var(--text-2)}.notification h2{font-size:1rem;line-height:1.5}.notification a{font-weight:500;text-decoration:none}.unread-mark{width:6px;height:6px;border-radius:var(--r-full);background:var(--primary);display:inline-block;margin-left:.5rem}.notification .change-block{margin-top:.75rem}.notification .caption{margin-top:.5rem}.profile-summary{display:flex;gap:1rem;align-items:center}.profile-summary h2{font-size:1.25rem}.settings-grid{display:grid;gap:2rem}.book-row{padding:1.5rem 0;border-bottom:1px solid var(--border);display:grid;grid-template-columns:40px 1fr;gap:1rem}.book-cover{border:1px solid var(--border);border-left:3px solid var(--primary);height:56px;border-radius:2px;background:var(--surface-2);display:flex;align-items:center;justify-content:center;color:var(--primary);font-size:.75rem}.book-row h2{font-size:1rem;line-height:1.5}.book-row p{margin:.4rem 0;font-size:.875rem;color:var(--text-2)}details{border:1px solid var(--border);border-radius:var(--r-md);background:var(--surface)}summary{display:flex;align-items:center;padding:.75rem 1rem;color:var(--primary);cursor:pointer;font-size:.875rem;font-weight:500}summary:after{content:'+';margin-left:auto;font-size:1.25rem}details[open]>summary:after{content:'−'}details>div{padding:0 1rem 1rem}.combo{background:var(--primary-soft-bg);border-radius:var(--r-lg);padding:1.5rem;color:var(--text)}.combo h2{font-size:1.25rem}.combo .price{font-size:1.5rem;font-weight:500;white-space:nowrap}.combo p{margin:.75rem 0}.combo details{background:var(--surface)}.map-plan{border:1px solid var(--border);border-radius:var(--r-lg);padding:1rem;background:var(--surface-2);display:grid;grid-template-columns:1fr 1fr;gap:.75rem}.map-room{padding:1.25rem .5rem;border:1px solid var(--control-border);border-radius:var(--r-sm);background:var(--surface);color:var(--primary);font-weight:600}.map-room[aria-pressed=true]{border:2px solid var(--primary)}.corridor{grid-column:1/-1;text-align:center;color:var(--text-2);font-size:.75rem;padding:.75rem 0}.ranking-row{display:grid;grid-template-columns:2rem 1fr auto;align-items:center;gap:.5rem;padding:1rem .75rem;border-bottom:1px solid var(--border)}.ranking-row.self{background:var(--primary-soft-bg);color:var(--primary-soft-text);border-radius:var(--r-md);border:0}.ranking-row.self .badge{background:var(--surface);color:var(--text)}.staff-grid{display:grid;gap:2rem}.staff-metrics{display:flex;gap:2rem;padding:1.25rem 0;border-block:1px solid var(--border)}.staff-metrics .metric{font-size:2rem}.document-paper{background:var(--surface);padding:2rem 1.5rem;border:1px solid var(--border);border-radius:var(--r-md);line-height:1.9}.document-paper h2{margin:2rem 0;font-family:Georgia,serif;text-align:center}.document-watermark{color:var(--text-2);font-size:.875rem;text-align:center;border-bottom:1px solid var(--border);padding-bottom:1rem}.skeleton{border-radius:var(--r-sm);background:linear-gradient(100deg,var(--surface-2) 40%,var(--surface) 50%,var(--surface-2) 60%);background-size:200% 100%;height:1rem;margin:.75rem 0;animation:shimmer 1.4s linear infinite}.skeleton.title{height:1.5rem;width:65%}.skeleton.short{width:40%}.skeleton.block{height:5rem}.state-example{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);padding:1.5rem;margin:1.5rem 0}.state-example>h2{font-size:1rem;margin-bottom:1.5rem;color:var(--text-2)}.component-grid{display:grid;gap:1.5rem}.component-item{padding:1.5rem;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg)}.component-item>h2{margin-bottom:1.25rem}.focus-demo{outline:2px solid var(--primary);outline-offset:3px}.pressed-demo{background:var(--primary-pressed)!important;color:var(--on-primary)!important}.offline-banner{background:var(--surface-2);color:var(--text-2);padding:.75rem 1rem;font-size:.875rem;border-bottom:1px solid var(--border)}.offline-retry{background:var(--clear);color:inherit;font:inherit;font-weight:600;text-decoration:underline}.toast{position:fixed;z-index:60;bottom:90px;left:1rem;right:1rem;margin:auto;max-width:600px;padding:1rem 1.25rem;border:0;border-radius:var(--r-md);background:var(--text);color:var(--bg);box-shadow:var(--e3);font-size:.875rem}dialog{background:var(--surface);color:var(--text);border:1px solid var(--border);border-radius:var(--r-xl);padding:1.5rem;max-width:calc(100% - 2rem);width:420px;max-height:calc(100dvh - 2rem);overflow:auto;box-shadow:var(--e3)}dialog::backdrop{background:var(--overlay)}dialog h2{margin-bottom:.75rem}dialog .actions{margin-top:1.5rem}dialog p{font-size:.875rem;color:var(--text-2)}.footer{border-top:1px solid var(--border);margin-top:3rem;padding:1.5rem 0 1rem;font-size:.75rem;color:var(--text-2)}/* подвал рендерится ПОСЛЕ .shell (partials/footer.csp) — контенту подвала та же сетка каркаса, что у .header-inner/.shell: max-width 1200 + боковые паддинги 1rem (2rem на ≥1024px); бордер-top остаётся на всю ширину */.footer-top{display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap;max-width:1200px;margin:auto;padding:0 1rem}.footer-links{display:flex;gap:1rem;flex-wrap:wrap}.footer-links a{font-size:.75rem}.disclaimer{max-width:28rem}[hidden]{display:none!important}@keyframes shimmer{to{background-position:-200% 0}}
@media(min-width:600px){.next-class{padding:2rem}.next-time{font-size:2.75rem}.service-grid{grid-template-columns:repeat(3,1fr)}.service-link{align-items:flex-start;flex-direction:column}.room-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.two-col{display:grid;grid-template-columns:1fr 1fr;gap:1rem}.page-heading .serif{font-size:2.75rem}.header-date{display:inline;font-size:.75rem;color:var(--text-2)}.lesson{grid-template-columns:4.5rem minmax(0,1fr) 5rem;gap:1.5rem}.lesson-subject{font-size:1rem}.component-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(min-width:1024px){.header-inner{padding:0 2rem;min-height:80px}.header-actions{gap:1rem}.primary-nav{position:static;border:0;background:var(--clear);padding:0;gap:.25rem;justify-content:center;flex:1}.nav-link{width:auto;min-height:80px;flex-direction:row;padding:.5rem 1rem;font-size:.875rem;position:relative}.nav-link .icon{display:none}.nav-link[aria-current]:after{content:'';position:absolute;left:1rem;right:1rem;bottom:0;height:2px;background:var(--primary)}.shell{padding:0 2rem 2rem}.page-heading{padding:2.75rem 0 2rem}.greeting-note{display:block;max-width:14rem;color:var(--text-2);font-size:.875rem}.dashboard-grid{grid-template-columns:minmax(0,1.85fr) minmax(0,1fr);gap:2.5rem}.dashboard-side{padding-left:2rem;border-left:1px solid var(--border)}.dashboard-side .section:first-child{margin-top:0}.next-time{font-size:3rem}.next-class h2{font-size:1.625rem}.next-top{display:flex;justify-content:space-between;align-items:center;gap:1rem}.next-top .badge{font-size:.75rem}.next-location{margin-top:1.75rem}.service-link{flex-direction:row;align-items:center}.settings-grid{grid-template-columns:1fr 1fr;gap:3rem}.room-layout{display:grid;grid-template-columns:minmax(0,1.7fr) minmax(0,1fr);gap:2.5rem}.booking-summary{position:sticky;top:104px;margin-top:0;align-self:start}.room-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.staff-label{display:inline;font-size:.875rem;color:var(--text-2);margin-left:1rem}.staff-grid{grid-template-columns:1.3fr 1fr;gap:3rem}.toast{bottom:2rem}.login-layout{padding-top:1rem}.map-layout{display:grid;grid-template-columns:320px 1fr;gap:3rem}.map-plan{min-height:320px;padding:2rem}.calendar-toolbar{margin-top:.5rem}/* сетка недели (и «Сегодня») на десктопе — на всю ширину shell: сегмент несёт каркасный .content-narrow (720px = ~2/3 при 1168px контента), ID-скоуп шире не делает мобильную вёрстку (правка только в ≥1024px); колонки дней .week-columns растягиваются на всю ширину контейнера сами (блочный grid) */
#schedule-segment{max-width:1200px}.week-columns{display:grid;grid-template-columns:1fr 1fr;gap:0 2rem}.footer{margin-top:4rem}.footer-top{padding:0 2rem}}
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important;scroll-behavior:auto!important}}
@media print{body{background:var(--surface)}.site-header,.primary-nav,.footer,.button,.page-heading,.toast,.skip{display:none!important}.shell{padding:0;max-width:none}.document-paper{border:0;padding:0;border-radius:0}.document-watermark{font-size:1rem}.print-only{display:block}}
.row>.icon-button{min-width:44px;flex-shrink:0}.week-strip{gap:2px}.day-pill{min-width:44px}
/* Дашборд «Сегодня» (экран Э7): точка срочности дедлайна 8px (03 §4.2:
   норма --border, ≤3 дней --warning-text, завтра --danger-text — только
   существующие токены, новых цветовых пар нет); виджет-карточки-ссылки
   (a.next-class/a.lesson — блочный якорь вместо inline-flex глобального a);
   пустые состояния виджетов; прошедшие пары дня — --text-3 (03 §4.2). */
.deadline-dot{display:inline-block;width:8px;height:8px;border-radius:var(--r-full);background:var(--border);margin-right:.5rem}.deadline-dot.dot-warn{background:var(--warning-text)}.deadline-dot.dot-danger{background:var(--danger-text)}.widget-empty{margin-top:.5rem;display:grid;gap:.75rem;justify-items:start}.widget-error{font-size:.875rem;color:var(--danger-text);margin-top:.4rem}a.next-class{display:block;color:var(--text);text-decoration:none}.next-room-line{margin-top:.75rem}a.lesson{color:var(--text);text-decoration:none}.lesson.is-past .lesson-subject,.lesson.is-past .lesson-time strong{color:var(--text-3)}
/* ==== Экран «Расписание» (Э7, 03 §4.3): статусы пар (перенос — левый
   акцент --warning-text + бейдж warning; отмена — зачёркнуто), стрелки
   недели, индикатор htmx (штатный паттерн .htmx-indicator), sheet «Детали
   пары» (dialog → bottom-sheet на <600px). Цвета — только существующие
   токены: пара --warning-text/--warning-bg уже покрыта
   tools/contrast_check.py (0 FAIL). Карточка пары — <button>: сброс
   кнопочных умолчаний, сетка .lesson общая; фокус — глобальный
   :focus-visible каркаса (2px --primary). ==== */
button.lesson{width:100%;border:0;background:var(--clear);padding:1.1rem 0;font:inherit;color:inherit;text-align:left;cursor:pointer}
/* акцентная линия переноса (.lesson.moved inset box-shadow) у первой/
   последней пары пересекала скруглённую границу списка: border-radius без
   overflow потомков не клипит — клип по радиусу карточки (линия обрезается
   точно по углам, и телефон, и десктоп) */
.schedule-list{overflow:hidden}
.lesson.moved{box-shadow:inset 3px 0 0 0 var(--warning-text)}
.lesson.moved .lesson-detail{color:var(--warning-text)}
.lesson.cancelled .lesson-subject,.lesson.cancelled .lesson-time strong{text-decoration:line-through;color:var(--text-3)}
.lesson.cancelled .lesson-detail{color:var(--text-3)}
.lesson.cancelled .lesson-room s{color:var(--text-3)}
.badge.warn{background:var(--warning-bg);color:var(--warning-text)}
.lesson-was{display:flex;align-items:center;flex-wrap:wrap;gap:.35rem;font-size:.875rem;color:var(--warning-text);margin-top:.35rem}
.lesson-was s{color:var(--text-2)}
.week-nav{display:flex;align-items:center;gap:.5rem}
.week-nav [data-week-range]{min-width:11ch;text-align:center}
.day-group.is-today>.section-title h2{color:var(--primary)}
.day-group.is-today .schedule-list{border:2px solid var(--primary);border-radius:var(--r-lg)}
.day-empty{padding:1.1rem 0;margin:0}
.htmx-indicator{opacity:0;transition:opacity 200ms ease-in}
.htmx-request .htmx-indicator,.htmx-request.htmx-indicator{opacity:1}
.sheet-row{display:flex;align-items:baseline;justify-content:space-between;gap:1rem;padding:.7rem 0;border-bottom:1px solid var(--border)}
.sheet-label{color:var(--text-2);font-size:.875rem;flex-shrink:0}
@media(max-width:599px){dialog.lesson-sheet{margin:auto auto 0;width:100%;max-width:none;border-radius:var(--r-xl) var(--r-xl) 0 0;border-bottom:0}}

/* Успеваемость (Э7, экран 2 из 2; 03 §4.4/§4.9.3): карточки дисциплин,
   баллы по компонентам, «Сессия». Цвета — только токены tokens.css:
   пороговые цвета прогресса 03 §4.4 (≥60 --success-text, 40–59
   --warning-text, <40 --danger-text) на --surface — пары из baseline
   tools/contrast_check.py (0 FAIL, PASS обеих тем); новая пара не
   вводилась. Цифры — tnum (03 §2.3): глобально font-feature-settings:
   'tnum' на body (строка 11), класс .tnum дублирует для явности. */
.tnum{font-variant-numeric:tabular-nums}
.grade-list{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);padding:0 1rem}
.discipline-row:last-child,.grade-component:last-child,.exam-row:last-child{border-bottom:0}
.grade-meter{margin-top:.75rem}
.grade-meter .progress{flex:1;margin:0}
.progress.ok:before{background:var(--success-text)}
.progress.warn:before{background:var(--warning-text)}
.grade-missing{color:var(--warning-text);margin-top:.5rem}
.grade-component{padding:1.1rem 0;border-bottom:1px solid var(--border)}
.grade-component .progress{margin-top:.6rem}
.grade-retake{color:var(--danger-text);margin-top:.4rem}
.badge-col{display:flex;flex-direction:column;align-items:flex-end;gap:.4rem;flex-shrink:0}
.exam-row{display:flex;align-items:center;justify-content:space-between;gap:1rem;min-height:44px;padding:1rem 0;border-bottom:1px solid var(--border);color:var(--text);text-decoration:none}
.exam-row p{margin-top:.25rem}
.exam-row .exam-when{white-space:nowrap;font-weight:500}
.exam-kind-retake{color:var(--danger-text)}

/* ==== Экран «Заявки» (Э7, 03 §4.5): список, форма, карточка. Новых
   цветовых пар НЕТ (Р-16): .notice.warn и точки таймлайна — существующие
   пары --warning-text/--warning-bg и --danger-text на --surface/warning-bg
   из baseline tools/contrast_check.py (0 FAIL, PASS обеих тем);
   button.document-type — сброс нативных стилей кнопки до вида
   .document-type (черновик application-catalog.html); .skeleton.card —
   скелетон строки каталога (03 §5.1:980 «2 карточки со строками»). */
.app-list{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);padding:0 1rem}
.app-card{display:block;padding:1.25rem 0;border-bottom:1px solid var(--border);color:var(--text);text-decoration:none}
.app-card:last-child{border-bottom:0}
.app-card h3{font-size:.9375rem;max-width:75%}
.app-card .caption{margin-top:.25rem}
button.document-type{width:100%;background:var(--surface);font:inherit;text-align:left;cursor:pointer}
.notice.warn{background:var(--warning-bg);border-color:var(--warning-text);color:var(--warning-text)}
.timeline li.warn:before{background:var(--warning-text);border-color:var(--warning-text)}
.timeline li.stop:before{background:var(--danger-text);border-color:var(--danger-text)}
.timeline li.future{color:var(--text-3)}
.skeleton.card{height:4.5rem}

/* ==== Экран «Бронь аудиторий» (Э7, 03 §4.9.5): каталог чипами, сетка
   слотов дня, «Мои брони», ghost-ссылка в шапке расписания. Сетка слотов
   — .room-grid/.room-slot из портированной базы (design-drafts).
   Новых цветовых пар НЕТ (Р-16): booked — нейтральный disabled слот
   (база .room-slot:disabled), mine — пара --primary-soft-text на
   --primary-soft-bg с бордером --primary (база .room-slot.mine), inline
   «заняли/заблокировали» — .notice.warn (--warning-text/--warning-bg),
   danger-диалог — .button.danger-button (--danger-*); все пары —
   baseline tools/contrast_check.py (0 FAIL, PASS обеих тем).
   Скелетоны секций: .skeleton.pill (чипы), .skeleton.slot (сетка). ==== */
.rooms-cap-field{display:flex;flex-direction:column;gap:.25rem;min-width:11rem}
.rooms-cap-field label{margin:0}
.rooms-date-field{display:flex;flex-direction:column;gap:.25rem}
.rooms-date-field label{margin:0}
.rooms-date-field input{width:auto}
.rooms-room-line{margin:-.5rem 0 .75rem}
.skeleton.pill{width:11rem;height:2.25rem;border-radius:var(--r-full)}
.skeleton.pill.short{width:8rem}
.skeleton.slot{height:4.75rem}
/* «ваша бронь» — акцент и в disabled (правило черновика .room-slot.mine
   перекрыто идущей позже .room-slot:disabled — уточняем специфичность,
   декларации те же, что .room-slot.mine базы) */
.room-slot.mine:disabled{background:var(--primary-soft-bg);border:2px solid var(--primary);color:var(--primary-soft-text);cursor:default}
.booking-row{display:flex;align-items:center;gap:1rem;padding:1rem 0;border-bottom:1px solid var(--border)}
.booking-row:last-child{border-bottom:0}
.booking-main{flex:1;min-width:0}
.booking-main strong{font-weight:500;display:block}
.booking-main span{display:block}
.booking-when{white-space:nowrap;font-size:.875rem;font-weight:500}
.booking-row .button{flex-shrink:0}
.rooms-ghost{gap:.35rem}
@media(max-width:599px){.booking-when{white-space:normal}}
/* Действие тоста (правки по ревью экрана; 03 §2.8: «действие справа»
   в тосте). Цвет — --bg на инверсном тосте (bg тоста = --text): пара
   ('bg','text') из baseline tools/contrast_check.py — 10.6:1 светлая /
   15.4:1 тёмная тема, PASS. «Цветом --primary» из 03 §2.8 на инверсном
   тосте WCAG НЕ проходит (замер WCAG-формулой: 2.0:1 светлая, 1.62:1
   тёмная) — осознанное отклонение цвета действия при сохранении самого
   действия (текст + ссылка «Мои брони» 03 §4.9.5). */
.toast{display:flex;align-items:baseline;justify-content:space-between;gap:1rem}
.toast-action{color:var(--bg);font-weight:600;text-decoration:underline;text-underline-offset:2px;flex-shrink:0}
/* ==== Экран «Уведомления» (views/notifications.csp, 03 §4.6/§5.1) ====
   Строки ленты — tappable-вариант каркасного .notification (черновик
   notifications.html): <a> с deep_link / <button> без него — сброс
   кнопочных умолчаний блочным паттерном button.lesson. Состояния
   прочитанности — спека 03 §4.6: непрочитанное — вес 600 заголовка +
   точка .unread-mark (каркасная), прочитанное — заголовок/иконка
   --text-2, время --text-3. Скелетон — 4 строки «иконка-круг 24 + 2
   строки текста» (03 §5.1) поверх shimmer-баз .skeleton. Новых цветов
   НЕТ — только существующие токены (AGENTS §5.6); пары текст/фон
   (--text-2/--text-3/--text на bg/surface) покрыты baseline
   tools/contrast_check.py — 0 FAIL. ==== */
.notifications-toolbar{margin-top:.25rem}
a.notification,button.notification{width:100%;border:0;background:var(--clear);padding:1.25rem 0;font:inherit;color:inherit;text-align:left;cursor:pointer}
.notification .ntitle{font-size:1rem;line-height:1.5}
.notification.is-unread .ntitle{font-weight:600}
.notification.is-read .ntitle{font-weight:400;color:var(--text-2)}
.notification.is-read>.icon{color:var(--text-3)}
.notification .nbody{font-size:.875rem;color:var(--text-2);margin-top:.25rem}
.notification .nwhen{font-size:.75rem;color:var(--text-3);margin-top:.5rem}
.notif-skeleton{display:grid;grid-template-columns:24px minmax(0,1fr);gap:.75rem;padding:1.25rem 0;border-bottom:1px solid var(--border)}
.notif-skeleton:last-child{border-bottom:0}
.notif-skeleton .skeleton{margin:0}
.notif-skeleton .sk-icon{width:24px;height:24px;border-radius:var(--r-full)}
.notif-skeleton .sk-lines{display:grid;gap:.5rem;align-content:start}
/* 5.17: сегменты «Уведомления | Новости | События» — каркасный .segments
   (03 §2.8), отступ до содержимого вкладки; строки новостей/событий —
   бейдж категории + дата публикации (flex-wrap на 360px), заголовок
   весом 600 (редакционная лента — состояния прочитанности НЕТ, точек
   нет), дата/место события и тело — --text-2, дата публикации --text-3
   (как .nwhen). Скелетон новости — бейдж-пилюля вместо иконки-круга.
   Новых цветовых пар НЕТ — только baseline-токены contrast_check. */
.notifications-segments{margin:0 0 1rem}
.news-item{border-bottom:1px solid var(--border);padding:1.25rem 0}
.news-item:last-child{border-bottom:0}
.news-item .news-head{display:flex;align-items:center;justify-content:space-between;gap:.5rem;flex-wrap:wrap}
.news-item .news-date{font-size:.75rem;color:var(--text-3)}
.news-item h2{font-size:1rem;line-height:1.5;font-weight:600;margin-top:.6rem}
.news-item .news-meta{font-size:.875rem;color:var(--text-2);margin-top:.35rem}
.news-item .news-body{font-size:.875rem;color:var(--text-2);margin-top:.5rem}
.notif-skeleton .sk-badge{width:72px;height:20px;border-radius:var(--r-full)}

/* ==== Экран «Профиль» (views/profile.csp, 03 §4.7; Э7, экран 4 из 4) ====
   QR-карточка (5.9) и читательский билет (5.12), настройки уведомлений,
   тема, ICS-подписка, онбординг С5. Новых цветовых пар НЕТ (Р-16):
   строки/опции — каркасные .option/.list-row; «тихие часы» — каркас
   input + .caption; ошибки секций — .widget-error-паттерн 03 §5.3
   (--danger-text на --bg, baseline contrast_check PASS). QR печатается
   ТОЛЬКО светлой парой существующих токенов --surface (#FFFFFF) /
   --text (#273F3A) — пара ('text','surface') из baseline
   tools/contrast_check.py (PASS обеих тем, 0 FAIL): код сканируется
   камерой и не тематизируется — как бумажный билет; пиксели красит
   app.js (Р-21), canvas здесь — только размер/рамка. ==== */
.library-row{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding-top:1.25rem;border-top:1px solid var(--border)}
.library-row strong{font-weight:500;display:block}
.library-row p{margin-top:.25rem}
.library-row .button{flex-shrink:0}
.quiet-row{display:grid;gap:.5rem;padding:.9rem 1rem;border:1px solid var(--control-border);border-radius:var(--r-md);background:var(--surface)}
.quiet-inputs{display:flex;align-items:center;gap:.5rem}
.quiet-inputs input{width:auto;min-width:7.5rem;flex:1}
.quiet-inputs span{color:var(--text-2)}
.ics-url{overflow-wrap:anywhere;font-weight:500}
.ics-url+.actions{margin-top:.25rem}
/* QR (5.9: sheet на весь тап, QR ~240px, имя и номер под ним, закрытие
   тапом) — dialog.lesson-sheet (bottom-sheet на <600px) каркаса */
.qr-wrap{display:flex;justify-content:center;padding:1rem 0}
.qr-canvas{display:block;width:min(280px,80vw);height:auto;border:1px solid var(--border);border-radius:var(--r-md)}
/* Онбординг С5 (03 §4.7/§4.9.4): счётчик N/4, полоса 25%/шаг
   (--value для каркасного .progress:before ставит app.js), строки 48px
   с кругом статуса (выполнен — --primary + ✓, впереди — --control-border);
   готовый шаг disabled. «Пропустить» — каркасный .button.ghost. */
.ob-progress{margin:.5rem 0 .75rem}
.ob-steps{display:grid;gap:.25rem}
button.ob-step{display:flex;align-items:center;gap:.75rem;min-height:48px;padding:.25rem .5rem;border:0;background:var(--clear);color:var(--text);font:inherit;text-align:left;border-radius:var(--r-sm)}
button.ob-step:disabled{cursor:default}
.ob-step .ob-mark{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;flex:none;border-radius:var(--r-full);border:2px solid var(--control-border);color:var(--on-primary);font-size:.75rem;line-height:1}
.ob-step[aria-pressed=true] .ob-mark{background:var(--primary);border-color:var(--primary)}
.ob-step[aria-pressed=true]{color:var(--text-2)}
.ob-step:not(:disabled):hover{background:var(--surface-2)}
.ob-footer{display:flex;align-items:center;justify-content:space-between;gap:1rem}
.ob-footer p{margin:0}

/* ==== Экран «Люди» (views/people.csp, views/person.csp; 03 §4.9.6,
   Э7, группа «Люди») ================================================
   Каталог-поиск (input + чипы ролей, строки → /people/{id}) и профиль
   человека. Шаблон ветвится ПО ДАННЫМ ОТВЕТА PeopleService::profile:
   преподаватель/сотрудник — mailto «Написать» и кабинет ссылкой
   /map/rooms?q=<номер>; чужой студент — ТОЛЬКО публичные поля (имя уже
   маскировано сервером, Р-15 — рисуем как пришло), блоков оценок/заявок
   нет даже заглушками (02 §5.2). Блок «Занятия» — компоненты каркаса
   .schedule-list/.lesson (статусы — классы экрана «Расписание»).
   Новых цветовых пар НЕТ (Р-16): .people-list повторяет каркасный
   паттерн списков (--surface/--border --r-lg — как .app-list/.grade-list),
   строки — каркасное .list-row; подсказка/пусто/ошибка — каркасные
   .empty/.surface/.section (текст на --bg/--surface — baseline
   tools/contrast_check.py, 0 FAIL); скелетоны — shimmer-база
   .skeleton.card. ==== */
.people-list{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);padding:0 1rem}
.people-list .list-row p{margin-top:.15rem}

/* ==== Стол сотрудника (views/staff.csp, views/staff/app_card.csp;
   03 §4.8, Э7 — последний экран) ====================================
   Сводка (счётчики очереди + «свежие изменения»), очередь заявок
   (чипы-фильтры, карточки .app-card с кнопками переходов матрицы),
   форма переноса и объявления. Карточка очереди — каркасная .app-card
   (как в списках заявок студента); кнопки в карточке — каркасная
   .button (actions wrap). Новых цветовых пар НЕТ (Р-16): бейдж
   «Срок горит» — .badge.danger (--danger-bg/--danger-text), статусы —
   .badge.info/.warn/.success/.outline, предупреждение в карточке —
   .field-error (--danger-text), результаты форм — .notice.success
   (--primary-soft-*) — все пары baseline tools/contrast_check.py
   (0 FAIL, PASS обеих тем). Скелетоны — shimmer-база (.skeleton/.card). */
.staff-sub-title{margin-top:2rem}
.staff-metrics{flex-wrap:wrap;gap:1rem 1.75rem}
.staff-changes,.staff-feed{list-style:none;margin:.75rem 0 0;padding:0}
.staff-changes li,.staff-feed li{border-bottom:1px solid var(--border)}
.staff-changes li:last-child,.staff-feed li:last-child{border-bottom:0}
.staff-change{display:block;padding:1rem 0;color:var(--text);text-decoration:none}
.staff-change strong{font-size:.9375rem;line-height:1.45}
.staff-change .caption{margin-top:.3rem}
.staff-change p{margin-top:.25rem}
.staff-feed li{padding:1rem 0}
.staff-feed li p{margin-top:.35rem}
.staff-actions{margin-top:.75rem}
.staff-actions-done{margin-top:.6rem}
#queue .chips{margin-bottom:.5rem}
button.chip{font:inherit;cursor:pointer}
/* подписи кнопок переходов — одной строкой: глобальный overflow-wrap:anywhere
   при flex:1 сжимал кнопки до побуквенного переноса («Тре буе тся уточне ние»).
   nowrap + min-width:max-content (каркасный min-width:44px перекрывает
   automatic minimum flex-элемента — без него кнопки сжимаются, а текст
   переполняет их): min-content кнопки = ширине подписи —
   .actions{flex-wrap:wrap} переносит кнопки ЦЕЛИКОМ
   (тап-зона .button ≥48px сохранена) */
.staff-actions .button{white-space:nowrap;min-width:max-content}

/* ==== 5.18: компактный переключатель языка в подвале
   (partials/footer.csp; сегмент в профиле — каркасный .segments) =====
   Три текстовые кнопки-автонима (Рус · EN · 中文) в одну строку под
   .footer-top — подвал компактный (03 §2.8), без капсулы .segments;
   активная — aria-pressed (подсветка ставит app.js по cookie para_lang /
   GET настроек). Новых цветовых пар НЕТ (Р-16): --primary на --bg —
   базовая пара каркаса (baseline tools/contrast_check.py); тап-зона
   уменьшена до 32px против каркасных 44 — это второстепенный элемент
   подвала, а не основной контрол (компромисс компактности 03 §2.8);
   @media print скрывает .footer целиком — переключатель уходит с ним. */
.lang-switch{display:flex;gap:.35rem;align-items:center;justify-content:center;flex-wrap:wrap;max-width:1200px;margin:.9rem auto 0;padding:0 1rem}
.lang-switch button{background:none;border:0;padding:.25rem .4rem;min-height:32px;font:inherit;font-size:.75rem;color:var(--text-2);cursor:pointer;border-radius:var(--r-sm)}
.lang-switch button:hover{color:var(--text)}
.lang-switch button[aria-pressed=true]{color:var(--primary);font-weight:600}
.lang-switch span{color:var(--text-2)}
