:root{--bg:#fafafa;--bg-2:#ffffff;--panel:#ffffff;--panel-2:#fafafa;--card:#ffffff;--line:#eaeaea;--line-2:#e2e2e2;--line-3:#d1d1d1;--tx:#000000;--tx-2:#666666;--tx-3:#999999;--accent:#000000;--accent-2:#171717;--accent-dim:#f4f4f4;--ok:#067a57;--ok-bg:#edfdf4;--ok-line:#a6e6c6;--warn:#9a5b09;--warn-bg:#fff7ed;--warn-line:#f3cfa0;--bad:#d12d36;--bad-bg:#fff1f1;--bad-line:#f4b8ba;--info:#0064e0;--info-bg:#f0f6ff;--info-line:#aecbf8;--mut:#666;--mut-bg:#f4f4f4;--t-scratch:#c2410c;--t-scratch-bg:#fff4ec;--t-scratch-line:#f3c49a;--t-python:#1a56db;--t-python-bg:#f0f5ff;--t-python-line:#aac1f4;--t-vibe:#067a57;--t-vibe-bg:#edfdf4;--t-vibe-line:#a6e6c6;--t-groups:#a21570;--t-groups-bg:#fdf0f7;--t-groups-line:#e9aed0;--r:8px;--r-sm:6px;--ease:cubic-bezier(.2,0,0,1);--ease-out:cubic-bezier(.16,1,.3,1);--dur-1:.12s;--dur-2:.18s;--dur-3:.24s;--dur-spin:.7s;--dur-pulse:2.4s;--press:scale(.96);--t-fast:var(--dur-1) var(--ease);--t-base:var(--dur-2) var(--ease);--mono:"Geist Mono",ui-monospace,"SF Mono","JetBrains Mono",Menlo,monospace;--sans:"Geist","Inter",-apple-system,system-ui,"Segoe UI",Roboto,sans-serif;--shadow:0 1px 2px rgba(0,0,0,.05);--shadow-lg:0 1px 2px rgba(0,0,0,.06),0 14px 34px -12px rgba(0,0,0,.22)}*{box-sizing:border-box;margin:0;padding:0}html,body,#root{height:100%}body{background:var(--bg);color:var(--tx);font-family:var(--sans);font-size:14px;line-height:1.45;-webkit-font-smoothing:antialiased;letter-spacing:-.011em}a{color:inherit;text-decoration:none}button{font-family:inherit;color:inherit;cursor:pointer;border:none;background:none}input,select,textarea{font-family:inherit;font-size:14px}.mono,.num{font-family:var(--mono);font-variant-numeric:tabular-nums;letter-spacing:-.01em}.app{min-height:100%;display:flex;flex-direction:column}header.top{position:sticky;top:0;z-index:40;background:#ffffffd9;-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);border-bottom:1px solid var(--line)}.top-inner{max-width:1560px;margin:0 auto;padding:11px 20px;display:flex;align-items:center;gap:16px;flex-wrap:wrap}.brand{display:flex;align-items:center;gap:10px}.logo{width:30px;height:30px;border-radius:7px;background:#000;color:#fff;display:grid;place-items:center;font-weight:600;font-family:var(--mono);font-size:12px;letter-spacing:-.02em}.brand b{font-size:14px;letter-spacing:-.02em;font-weight:600}.brand span{display:block;font-size:11px;color:var(--tx-3)}nav.tabs{display:flex;gap:2px;margin-left:8px}nav.tabs a{padding:6px 12px;border-radius:7px;color:var(--tx-2);font-weight:500;font-size:13px}nav.tabs a{transition:background var(--dur-1) var(--ease),color var(--dur-1) var(--ease)}nav.tabs a.active{background:#000;color:#fff}nav.tabs a:not(.active):hover{background:var(--mut-bg);color:var(--tx)}.spacer{flex:1}.who{font-size:12px;color:var(--tx-2);text-align:right}.who b{display:block;color:var(--tx);font-weight:500}.wrap{max-width:1560px;margin:0 auto;padding:18px 20px 60px;width:100%}.btn{display:inline-flex;align-items:center;gap:7px;padding:7px 13px;border-radius:var(--r-sm);background:#fff;border:1px solid var(--line-2);font-weight:500;font-size:13px;color:var(--tx);transition:background var(--dur-1) var(--ease),border-color var(--dur-1) var(--ease),transform var(--dur-1) var(--ease),box-shadow var(--dur-1) var(--ease),opacity var(--dur-1) var(--ease);white-space:nowrap}.btn:hover{border-color:var(--tx-3);background:#fff}.btn:active:not(:disabled){transform:var(--press)}.btn.primary{background:#000;color:#fff;border-color:#000}.btn.primary:hover{background:#333;border-color:#333}.btn.warn{background:#fff;color:var(--warn);border-color:var(--warn-line)}.btn.warn:hover{background:var(--warn-bg)}.btn.bad{background:#fff;color:var(--bad);border-color:var(--bad-line)}.btn.bad:hover{background:var(--bad-bg)}.btn.ghost{background:transparent;border-color:transparent;color:var(--tx-2)}.btn.ghost:hover{background:var(--mut-bg);color:var(--tx)}.btn.sm{padding:5px 9px;font-size:12px;border-radius:var(--r-sm)}.btn:disabled{opacity:.45;cursor:not-allowed}.btn:focus-visible,.seg button:focus-visible,.scale button:focus-visible,.pop-actions button:focus-visible,nav.tabs a:focus-visible{outline:none;box-shadow:0 0 0 3px #00000014}.btn:has(.spin){min-width:7.5em;justify-content:center}.panel{background:var(--panel);border:1px solid var(--line);border-radius:var(--r)}.toolbar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:14px}.field{display:flex;flex-direction:column;gap:5px}.field label{font-size:12px;color:var(--tx-2);font-weight:500}.input,select.input{padding:8px 11px;border:1px solid var(--line-2);border-radius:var(--r-sm);background:#fff;color:var(--tx);min-width:120px}.input::placeholder{color:var(--tx-3)}.input:focus,select.input:focus{outline:none;border-color:#000}.input:focus-visible,select.input:focus-visible,textarea.input:focus-visible{box-shadow:0 0 0 3px #00000014}textarea.input{min-height:70px;resize:vertical}.input,select.input,textarea.input{transition:border-color var(--dur-1) var(--ease),box-shadow var(--dur-1) var(--ease)}.chip{display:inline-flex;align-items:center;gap:6px;padding:2px 8px;border-radius:999px;font-size:11px;font-weight:500;background:#fff;color:var(--tx-2);border:1px solid var(--line-2)}.chip.scratch{background:var(--t-scratch-bg);color:var(--t-scratch);border-color:var(--t-scratch-line)}.chip.python{background:var(--t-python-bg);color:var(--t-python);border-color:var(--t-python-line)}.chip.vibe{background:var(--t-vibe-bg);color:var(--t-vibe);border-color:var(--t-vibe-line)}.chip.groups{background:var(--t-groups-bg);color:var(--t-groups);border-color:var(--t-groups-line)}.chip.ok{background:var(--ok-bg);color:var(--ok);border-color:var(--ok-line)}.chip.warn{background:var(--warn-bg);color:var(--warn);border-color:var(--warn-line)}.chip.bad{background:var(--bad-bg);color:var(--bad);border-color:var(--bad-line)}.chip.info{background:var(--info-bg);color:var(--info);border-color:var(--info-line)}.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin-bottom:16px}.stat{padding:14px 16px;border-radius:var(--r);background:var(--panel);border:1px solid var(--line)}.stat .n{font-size:26px;font-weight:600;font-family:var(--mono);letter-spacing:-.03em}.stat .l{font-size:12px;color:var(--tx-2);margin-top:2px}table.tbl{width:100%;border-collapse:collapse;font-size:13px}table.tbl th{text-align:left;padding:9px 10px;color:var(--tx-3);font-weight:500;font-size:11px;text-transform:uppercase;letter-spacing:.04em;border-bottom:1px solid var(--line)}table.tbl td{padding:9px 10px;border-bottom:1px solid var(--line)}table.tbl tbody td{transition:background var(--dur-1) var(--ease)}table.tbl tr:last-child td{border-bottom:none}table.tbl tbody tr:hover td{background:var(--bg)}table.tbl tbody tr:focus-visible{outline:none}table.tbl tbody tr:focus-visible td{background:var(--bg)}table.tbl tbody tr:focus-visible td:first-child{box-shadow:inset 3px 0 #000}.overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#0006;display:grid;place-items:center;z-index:100;padding:20px;animation:ov-in var(--dur-2) var(--ease-out)}.modal{background:var(--panel);border:1px solid var(--line-2);border-radius:var(--r);box-shadow:var(--shadow-lg);max-width:560px;width:100%;max-height:90vh;overflow:auto;animation:mo-in var(--dur-3) var(--ease-out)}.modal.lg{max-width:780px}.modal-h{display:flex;align-items:center;gap:10px;padding:15px 20px;border-bottom:1px solid var(--line);position:sticky;top:0;background:var(--panel);z-index:1}.modal-h b{font-size:15px;font-weight:600}.modal-b{padding:18px 20px}.modal-f{padding:14px 20px;border-top:1px solid var(--line);display:flex;gap:10px;justify-content:flex-end;position:sticky;bottom:0;background:var(--panel)}.grid2{display:grid;grid-template-columns:1fr 1fr;gap:12px}.grid3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px}@media (max-width:640px){.grid2,.grid3{grid-template-columns:1fr}}.login-wrap{min-height:100%;display:grid;place-items:center;padding:20px}.login-card{width:100%;max-width:380px;padding:28px;border-radius:12px}.login-card h1{font-size:21px;margin-bottom:4px;font-weight:600;letter-spacing:-.02em}.login-card p{color:var(--tx-2);margin-bottom:18px;font-size:13px}.pop{position:fixed;z-index:120;width:300px;background:var(--panel);border:1px solid var(--line-2);border-radius:var(--r);box-shadow:var(--shadow-lg);overflow:hidden;animation:pop-in var(--dur-2) var(--ease-out);transform-origin:top center}.pop-h{padding:12px 14px;border-bottom:1px solid var(--line)}.pop-h .t{font-weight:600;font-size:14px}.pop-h .s{font-size:12px;color:var(--tx-2);margin-top:2px}.pop-actions{display:flex;flex-direction:column;padding:6px}.pop-actions button{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:var(--r-sm);font-size:13px;text-align:left;color:var(--tx);font-weight:500}.pop-actions button{transition:background var(--dur-1) var(--ease),color var(--dur-1) var(--ease)}.pop-actions button:hover{background:var(--mut-bg)}.pop-actions button.danger{color:var(--bad)}.pop-actions .div{height:1px;background:var(--line);margin:5px 6px}.muted{color:var(--tx-3)}.row{display:flex;align-items:center;gap:8px}.kv{display:grid;grid-template-columns:140px 1fr;gap:7px 12px;font-size:13px}.kv .k{color:var(--tx-2)}.scale{display:flex;gap:4px;flex-wrap:wrap}.scale button{width:32px;height:32px;border-radius:var(--r-sm);border:1px solid var(--line-2);font-weight:500;font-family:var(--mono);background:#fff}.scale button:hover{border-color:var(--tx-3)}.scale button.on{background:#000;color:#fff;border-color:#000}.seg{display:inline-flex;background:#fff;border:1px solid var(--line-2);border-radius:var(--r-sm);padding:3px;gap:3px}.seg button{padding:6px 14px;border-radius:4px;font-weight:500;font-size:13px;color:var(--tx-2)}.seg button.on{background:#000;color:#fff}.scale button,.seg button{transition:background var(--dur-1) var(--ease),border-color var(--dur-1) var(--ease),color var(--dur-1) var(--ease),transform var(--dur-1) var(--ease)}.scale button:active,.seg button:active{transform:var(--press)}.toast{position:fixed;bottom:20px;left:50%;transform:translate(-50%);background:#000;color:#fff;padding:11px 18px;border-radius:var(--r-sm);font-size:13px;z-index:200;box-shadow:var(--shadow-lg);animation:toast-in var(--dur-2) var(--ease-out)}.toast.bad{background:var(--bad)}.toast.ok{background:#000}.toast.leaving{animation:toast-out var(--dur-2) var(--ease-out) forwards}.fc{--fc-border-color:var(--line);--fc-page-bg-color:transparent;--fc-event-text-color:#18181b;--fc-today-bg-color:transparent;font-family:var(--sans)}.fc .fc-toolbar-title{font-size:17px;font-weight:600;letter-spacing:-.02em}.fc .fc-button{background:#fff;border:1px solid var(--line-2);color:var(--tx-2);font-weight:500;text-transform:none;box-shadow:none;border-radius:var(--r-sm);padding:6px 11px}.fc .fc-button{transition:background var(--dur-1) var(--ease),border-color var(--dur-1) var(--ease),color var(--dur-1) var(--ease)}.fc .fc-button:hover{background:var(--bg);color:var(--tx)}.fc .fc-button-primary:not(:disabled).fc-button-active{background:#000;color:#fff;border-color:#000}.fc .fc-button-primary:disabled{opacity:.4}.fc .fc-col-header-cell-cushion,.fc .fc-list-day-text{color:var(--tx-2);font-weight:500;font-size:12px}.fc .fc-timegrid-slot-label-cushion,.fc .fc-daygrid-day-number{color:var(--tx-3);font-family:var(--mono);font-size:11px}.fc .fc-timegrid-slot{height:3.05em}.fc .fc-event{border:1.5px solid var(--line-3);border-radius:6px;padding:1px 5px;font-size:12px;font-weight:600;cursor:pointer;overflow:hidden;background:#fff;color:#18181b;box-shadow:none}.fc .fc-event{transition:transform var(--dur-1) var(--ease-out),box-shadow var(--dur-1) var(--ease),opacity var(--dur-2) var(--ease)}.fc .fc-event:hover{transform:translateY(-1px);box-shadow:0 2px 6px -2px #0000002e;z-index:5}.fc .fc-event .fc-event-main,.fc .fc-event .fc-event-main-frame,.fc .fc-event .fc-event-title{color:#18181b}.fc .fc-event .fc-event-time{font-family:var(--mono);font-weight:500;color:#52525b;font-size:10.5px;opacity:1}.fc .fc-event.course-scratch{background:var(--t-scratch-bg);border-color:var(--t-scratch)}.fc .fc-event.course-python{background:var(--t-python-bg);border-color:var(--t-python)}.fc .fc-event.course-vibe{background:var(--t-vibe-bg);border-color:var(--t-vibe)}.fc .fc-event.course-groups{background:var(--t-groups-bg);border-color:var(--t-groups)}.fc .fc-event.held{opacity:.6}.fc .fc-event.cancelled{opacity:.6;text-decoration:line-through}.fc .fc-event.makeup{border-style:dashed;border-width:2px}.fc-event-main{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.fc .fc-daygrid-event .fc-event-time{margin-right:3px}.fc .fc-timegrid-now-indicator-line{border-color:#000;border-top-width:2px}.fc .fc-timegrid-now-indicator-arrow{border-color:#000;color:#000;animation:now-pulse var(--dur-pulse) ease-in-out infinite}.fc-theme-standard td,.fc-theme-standard th{border-color:var(--line)}.fc .fc-day-today{background:#00000004}.fc .fc-col-header-cell.fc-day-today .fc-col-header-cell-cushion,.fc .fc-day-today .fc-daygrid-day-number{color:var(--tx);font-weight:600}.legend{display:flex;gap:12px;flex-wrap:wrap;font-size:12px;color:var(--tx-2);align-items:center}.legend i{width:10px;height:10px;border-radius:3px;display:inline-block;margin-right:5px;vertical-align:-1px;border:1px solid rgba(0,0,0,.12)}.spin{display:inline-block;width:16px;height:16px;border:2px solid var(--line-2);border-top-color:#000;border-radius:50%;animation:sp var(--dur-spin) linear infinite}@keyframes sp{to{transform:rotate(360deg)}}@keyframes ov-in{0%{opacity:0}to{opacity:1}}@keyframes mo-in{0%{opacity:0;transform:translateY(6px) scale(.98)}to{opacity:1;transform:none}}@keyframes pop-in{0%{opacity:0;transform:translateY(-4px) scale(.97)}to{opacity:1;transform:none}}@keyframes toast-in{0%{opacity:0;transform:translate(-50%,8px)}to{opacity:1;transform:translate(-50%)}}@keyframes toast-out{to{opacity:0;transform:translate(-50%,8px)}}@keyframes now-pulse{0%,to{opacity:1}50%{opacity:.55}}::selection{background:#000;color:#fff}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-thumb{background:#d8d8d8;border-radius:8px}::-webkit-scrollbar-track{background:transparent}@media (prefers-reduced-motion: reduce){*,*:before,*:after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}.spin{animation:sp var(--dur-spin) linear infinite!important}}
