/* ========================================================================== librus-tui - AMOLED theme ========================================================================== */ :root { --bg: #000000; --bg-soft: #000000; --panel: #000000; --panel-raised: #0a0a0d; --panel-title: #0a0a0d; --accent: #7c9cff; --fg-bright: #f4f4f5; --accent-mid: #4f7cff; --dim: #8a8a94; --dimmer: #565660; --line: #26262c; --line-soft: #16161a; --amber: #fbbf24; --amber-dim: #7c5a12; --red: #fb7185; --red-dim: #7f1d2d; --cyan: #67e8f9; --violet: #c4b5fd; --black: #000000; --mono: "JetBrains Mono", "Cascadia Mono", "Cascadia Code", "Fira Code", "IBM Plex Mono", "Source Code Pro", ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; } * { box-sizing: border-box; } html, body { height: 100%; margin: 0; } body { background: var(--bg); color: var(--fg-bright); font-family: var(--mono); font-size: 13px; line-height: 1.45; font-variant-ligatures: none; -webkit-font-smoothing: antialiased; overflow: hidden; padding: 0; } ::selection { background: var(--accent); color: var(--black); } button, input { font-family: inherit; font-size: inherit; } button { color: inherit; } .hidden { display: none !important; } .dim { color: var(--dim); } .accent { color: var(--amber); } /* ------------------------------------------------------------------ CRT chrome */ .crt { position: relative; height: 100%; max-width: 100%; margin: 0; } .crt-scanlines, .crt-vignette, .crt-flicker { display: none !important; } .terminal { position: relative; z-index: 1; display: flex; flex-direction: column; height: 100dvh; min-height: 0; background: var(--bg); border: 0; box-shadow: none; overflow: hidden; } /* ------------------------------------------------------------------- titlebar */ .titlebar { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex: 0 0 29px; padding: 0 10px; background: #050508; border-bottom: 1px solid var(--line); box-shadow: inset 0 1px 0 rgba(124, 156, 255, 0.4); color: var(--fg-bright); font-size: 11.5px; font-weight: 700; letter-spacing: 0.4px; } .titlebar-name { color: var(--accent); } .titlebar-mark { color: var(--accent); font-size: 14px; } .titlebar-left, .titlebar-right { display: flex; align-items: center; gap: 8px; min-width: 0; white-space: nowrap; } .titlebar-mark { font-size: 14px; } .titlebar-sep, .titlebar-sub, .titlebar-date { opacity: 0.66; font-weight: 500; } .titlebar-clock { font-variant-numeric: tabular-nums; } .titlebar-right { font-weight: 500; font-size: 11px; } .badge { display: inline-block; padding: 0 5px; border: 1px solid currentColor; font-size: 9.5px; line-height: 15px; letter-spacing: 1px; font-weight: 700; } .demo-badge { color: #3c2a00; background: var(--amber); border-color: #3c2a00; } .led { width: 7px; height: 7px; border-radius: 50%; background: #15151a; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5) inset; } .led.online { background: var(--accent); box-shadow: 0 0 6px var(--accent); } .led.busy { background: var(--amber); animation: led-pulse 0.7s infinite alternate; } .led.offline { background: var(--red); } .badge { display: inline-block; padding: 0 5px; border: 1px solid currentColor; font-size: 9.5px; line-height: 15px; letter-spacing: 1px; font-weight: 700; } .demo-badge { color: #3c2a00; background: var(--amber); border-color: #3c2a00; } .led { width: 7px; height: 7px; border-radius: 50%; background: #15151a; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35) inset; } .led.online { background: var(--accent); box-shadow: 0 0 5px var(--accent); } .led.busy { background: var(--amber-dim); animation: led-pulse 0.7s infinite alternate; } .led.offline { background: var(--red-dim); } @keyframes led-pulse { from { opacity: 0.35; } to { opacity: 1; } } /* --------------------------------------------------------------------- screens */ .screen { flex: 1 1 auto; min-height: 0; overflow: hidden; } .login-screen { display: flex; overflow: auto; } .login-wrap { width: min(780px, 100%); margin: auto; padding: 34px 22px 26px; text-align: center; } .logo { display: inline-block; margin: 0; color: var(--accent); font-size: clamp(7px, 1.25vw, 13.5px); line-height: 1.12; text-shadow: 0 0 7px rgba(124, 156, 255, 0.55), 0 0 24px rgba(124, 156, 255, 0.18); user-select: none; } .logo-accent { color: var(--amber); text-shadow: 0 0 8px rgba(255, 206, 107, 0.6); } .logo-sub { margin: 8px 0 30px; color: var(--dim); font-size: 11px; letter-spacing: 2.4px; text-transform: uppercase; } .login-grid { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); gap: 16px; text-align: left; } .login-box, .bootlog-wrap { border: 1px solid var(--line); background: rgba(0, 0, 0, 0.72); padding: 12px 14px 14px; box-shadow: 0 0 18px rgba(0, 0, 0, 0.35) inset; } .box-rule { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; color: var(--dim); font-size: 9.5px; letter-spacing: 2px; } .box-rule::before, .box-rule::after { content: ""; flex: 1; height: 1px; background: var(--line-soft); } .field { display: block; margin-bottom: 13px; } .field-label { display: block; margin-bottom: 4px; color: var(--dim); font-size: 10px; letter-spacing: 1.6px; text-transform: uppercase; } .field-input-wrap { display: flex; align-items: center; gap: 7px; padding: 7px 8px; background: #000000; border: 1px solid var(--line); transition: border-color 0.12s, box-shadow 0.12s; } .field-input-wrap:focus-within { border-color: var(--accent-mid); box-shadow: 0 0 0 1px rgba(124, 156, 255, 0.12), 0 0 14px rgba(124, 156, 255, 0.1) inset; } .field-prompt { color: var(--accent-mid); } .field input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; color: var(--fg-bright); caret-color: var(--accent); } .field input::placeholder { color: #565660; } .btn { display: inline-block; padding: 7px 11px; border: 1px solid var(--line); background: transparent; color: var(--accent); font-size: 12px; letter-spacing: 0.5px; cursor: pointer; text-align: center; transition: background 0.1s, color 0.1s, border-color 0.1s; } .btn:hover, .btn:focus-visible { background: rgba(124, 156, 255, 0.12); border-color: var(--accent-mid); color: var(--fg-bright); } .btn:active { transform: translateY(1px); } .btn:disabled { opacity: 0.45; cursor: wait; } .btn-primary { width: 100%; margin-top: 4px; border-color: var(--accent-mid); background: rgba(124, 156, 255, 0.08); color: var(--fg-bright); text-transform: uppercase; letter-spacing: 1.6px; font-size: 11px; } .login-alt { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 12px; flex-wrap: wrap; } .login-note { color: var(--dimmer); font-size: 9.5px; letter-spacing: 0.8px; } #demo-btn { border-color: var(--amber-dim); color: var(--amber); font-size: 11px; } #demo-btn:hover { background: rgba(255, 206, 107, 0.1); border-color: var(--amber); } .bootlog-wrap { display: flex; flex-direction: column; min-height: 100%; } .bootlog { flex: 1; margin: 0; min-height: 142px; max-height: 230px; overflow: auto; color: var(--dim); font-family: inherit; font-size: 11px; line-height: 1.65; white-space: pre-wrap; word-break: break-word; } .bootlog .ok { color: var(--accent); } .bootlog .err { color: var(--red); } .bootlog .info { color: var(--cyan); } .bootlog .warn { color: var(--amber); } .bootlog .cmd { color: var(--fg-bright); } .login-hint { margin: 18px 0 0; color: var(--dimmer); font-size: 10px; line-height: 1.6; } /* ------------------------------------------------------------------- app shell */ .app-screen { display: flex; } .app-grid { display: grid; grid-template-columns: 206px minmax(0, 1fr); width: 100%; height: 100%; min-height: 0; } .sidebar { display: flex; flex-direction: column; gap: 1px; min-height: 0; padding: 10px 8px 8px; border-right: 1px solid var(--line-soft); background: rgba(0, 0, 0, 0.45); overflow-y: auto; } .side-head { padding: 0 8px 7px; color: var(--dimmer); font-size: 9px; letter-spacing: 2.2px; } .nav-item { display: flex; align-items: center; gap: 9px; width: 100%; padding: 5px 8px; border: 1px solid transparent; background: transparent; color: var(--dim); text-align: left; cursor: pointer; transition: background 0.1s, color 0.1s; } .nav-item:hover { color: var(--fg-bright); background: rgba(124, 156, 255, 0.06); } .nav-item.active { background: rgba(124, 156, 255, 0.14); border-color: rgba(124, 156, 255, 0.42); color: var(--fg-bright); font-weight: 700; box-shadow: inset 2px 0 0 var(--accent); } .nav-key { width: 13px; flex: 0 0 13px; color: var(--dimmer); font-size: 10.5px; text-align: center; } .nav-item.active .nav-key { color: var(--accent); } .nav-label { font-size: 12px; } .nav-muted { color: var(--dimmer); } .side-sep { height: 1px; margin: 7px 8px; background: var(--line-soft); } .side-spacer { flex: 1 1 auto; min-height: 18px; } .side-user { padding: 8px; border-top: 1px solid var(--line-soft); } .side-user-name { color: var(--fg-bright); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .side-user-meta { margin-top: 2px; color: var(--dim); font-size: 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .side-foot { display: flex; justify-content: space-between; padding: 7px 8px 0; color: var(--dimmer); font-size: 9px; letter-spacing: 0.3px; } .main { display: flex; flex-direction: column; min-width: 0; min-height: 0; } .view-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex: 0 0 31px; padding: 0 13px; border-bottom: 1px solid var(--line-soft); background: rgba(0, 0, 0, 0.62); font-size: 12px; } .view-path { display: flex; align-items: center; gap: 2px; white-space: nowrap; } .view-path #view-title { color: var(--fg-bright); } .cursor-block { display: inline-block; width: 7px; height: 13px; margin-left: 5px; background: var(--accent); animation: blink 1.1s steps(1) infinite; } @keyframes blink { 50% { opacity: 0; } } .view-meta { color: var(--dim); font-size: 10px; text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .view { flex: 1 1 auto; min-height: 0; padding: 13px; overflow: auto; outline: none; scrollbar-gutter: stable; } .view > .view-inner { max-width: 1400px; margin: 0 auto; } /* -------------------------------------------------------------------- panels */ .panel { min-width: 0; border: 1px solid var(--line); background: var(--bg); box-shadow: none; } .panel-title { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 3px 8px; border-bottom: 1px solid var(--line); background: var(--panel-title); color: var(--accent); font-size: 9.5px; letter-spacing: 1.5px; text-transform: uppercase; } .panel-title .title-note { color: var(--dim); letter-spacing: 0.4px; text-transform: none; font-size: 9.5px; } .panel-body { padding: 10px; } .panel-body.tight { padding: 6px 8px; } /* ------------------------------------------------------------------ dashboard */ .dash-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; align-items: start; } .span-2 { grid-column: span 2; } .span-3 { grid-column: 1 / -1; } .counters-panel { grid-column: span 2; } .identity { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; flex-wrap: wrap; } .identity-name { margin: 0; color: var(--fg-bright); font-size: clamp(20px, 2.1vw, 27px); line-height: 1.15; letter-spacing: -0.5px; text-shadow: 0 0 14px rgba(124, 156, 255, 0.25); } .identity-sub { margin-top: 3px; color: var(--dim); font-size: 11px; } .class-chip { display: inline-block; margin-left: 6px; padding: 0 6px; border: 1px solid var(--accent-mid); color: var(--accent); font-size: 10px; } .kv { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 3px 14px; margin: 12px 0 0; font-size: 11px; } .kv dt { color: var(--dim); } .kv dd { margin: 0; color: var(--accent); overflow-wrap: anywhere; } .lucky { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 128px; padding: 8px; } .lucky-number { color: var(--amber); font-size: clamp(46px, 5.5vw, 68px); font-weight: 700; line-height: 1; text-shadow: 0 0 12px rgba(255, 206, 107, 0.45), 0 0 36px rgba(255, 206, 107, 0.15); } .lucky-label { margin-top: 8px; color: var(--dim); font-size: 9.5px; letter-spacing: 1.6px; text-transform: uppercase; } .behaviour { display: flex; flex-direction: column; justify-content: center; min-height: 128px; padding: 8px; } .behaviour-grade { color: var(--fg-bright); font-size: clamp(17px, 1.8vw, 22px); line-height: 1.2; } .behaviour-teacher { margin-top: 7px; color: var(--dim); font-size: 10.5px; } .stat-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); } .stat { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; padding: 9px 12px; border: 0; border-right: 1px solid var(--line-soft); background: transparent; text-align: left; cursor: pointer; transition: background 0.1s; } .stat:last-child { border-right: 0; } .stat:hover { background: rgba(124, 156, 255, 0.06); } .stat-value { color: var(--fg-bright); font-size: 23px; line-height: 1.1; font-variant-numeric: tabular-nums; } .stat-label { color: var(--dim); font-size: 9.5px; letter-spacing: 1.1px; text-transform: uppercase; } .stat.warn .stat-value { color: var(--amber); } .lesson-list { display: flex; flex-direction: column; } .lesson-line { display: grid; grid-template-columns: 48px 10px minmax(0, 1fr) auto; gap: 7px; align-items: baseline; padding: 4px 2px; border-bottom: 1px dashed var(--line-soft); font-size: 11.5px; } .lesson-line:last-child { border-bottom: 0; } .lesson-line .time { color: var(--dim); font-size: 10.5px; font-variant-numeric: tabular-nums; } .lesson-line .marker { color: var(--dimmer); } .lesson-line .subject { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .lesson-line .room { color: var(--dim); font-size: 10px; } .lesson-line.now { background: rgba(124, 156, 255, 0.06); } .lesson-line.now .marker, .lesson-line.now .subject { color: var(--fg-bright); } .lesson-line.next .marker { color: var(--amber); } .lesson-line.cancelled .subject { color: var(--dimmer); text-decoration: line-through; } .freeday-line { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; padding: 5px 2px; border-bottom: 1px dashed var(--line-soft); font-size: 11.5px; } .freeday-line:last-child { border-bottom: 0; } .freeday-line .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .countdown { color: var(--dim); font-size: 9.5px; white-space: nowrap; } .countdown.soon { color: var(--amber); } .countdown.now { color: var(--fg-bright); } /* ------------------------------------------------------------------- toolbar */ .toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; color: var(--dim); font-size: 10.5px; } .toolbar .grow { flex: 1; } .toolbar kbd { margin: 0 1px; } .tool-input { width: min(230px, 100%); padding: 4px 7px; border: 1px solid var(--line); background: #000000; color: var(--fg-bright); outline: none; } .tool-input:focus { border-color: var(--accent-mid); box-shadow: 0 0 0 1px rgba(124, 156, 255, 0.12); } .tool-input::placeholder { color: var(--dimmer); } .btn-sm { padding: 3px 8px; font-size: 10.5px; } .btn-warn { border-color: var(--amber-dim); color: var(--amber); } /* -------------------------------------------------------------------- grades */ .grades-summary { display: flex; gap: 18px; flex-wrap: wrap; } .grades-summary b { color: var(--fg-bright); } .grades-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; align-items: start; } .subject-card .panel-title { text-transform: none; letter-spacing: 0.3px; font-size: 11px; } .subject-average { color: var(--amber); font-size: 10.5px; white-space: nowrap; } .grade-chips { display: flex; flex-wrap: wrap; gap: 6px; } .grade-chip { position: relative; display: inline-flex; flex-direction: column; align-items: flex-start; gap: 1px; min-width: 58px; padding: 4px 7px 3px; border: 1px solid var(--line); border-bottom-width: 2px; background: #050507; color: var(--accent); text-align: left; cursor: pointer; transition: background 0.1s, border-color 0.1s, transform 0.1s; } .grade-chip:hover { background: rgba(124, 156, 255, 0.07); transform: translateY(-1px); } .grade-chip .g { font-size: 17px; font-weight: 700; line-height: 1.1; } .grade-chip .g-meta { max-width: 110px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dim); font-size: 8.5px; letter-spacing: 0.2px; } .grade-chip .g-weight { position: absolute; top: 2px; right: 3px; color: var(--dimmer); font-size: 8px; } .grade-chip.g-excellent { border-bottom-color: var(--accent-mid); } .grade-chip.g-excellent .g { color: var(--fg-bright); } .grade-chip.g-good { border-bottom-color: var(--cyan); } .grade-chip.g-good .g { color: var(--cyan); } .grade-chip.g-ok { border-bottom-color: var(--amber); } .grade-chip.g-ok .g { color: var(--amber); } .grade-chip.g-bad { border-bottom-color: var(--red); } .grade-chip.g-bad .g { color: var(--red); } .grade-chip.g-none { border-bottom-color: var(--dimmer); } .grade-chip.g-none .g { color: var(--dim); } .grade-chip.final { border-style: dashed; background: rgba(124, 156, 255, 0.05); } .grade-chip.semester { outline: 1px solid var(--line); outline-offset: 2px; } .legend { display: flex; gap: 14px; flex-wrap: wrap; color: var(--dim); font-size: 9.5px; } .legend .swatch { display: inline-block; width: 8px; height: 8px; margin-right: 4px; border: 1px solid currentColor; } .legend .swatch.green { color: var(--accent-mid); background: rgba(124, 156, 255, 0.3); } .legend .swatch.cyan { color: var(--cyan); background: rgba(126, 232, 255, 0.25); } .legend .swatch.amber { color: var(--amber); background: rgba(255, 206, 107, 0.25); } .legend .swatch.red { color: var(--red); background: rgba(255, 119, 119, 0.25); } /* ----------------------------------------------------------------- timetable */ .timetable-scroll { overflow: auto; border: 1px solid var(--line); background: rgba(0, 0, 0, 0.55); } .timetable { display: grid; min-width: 780px; } .tt-cell { min-width: 0; min-height: 64px; padding: 4px 6px; border-right: 1px solid var(--line-soft); border-bottom: 1px solid var(--line-soft); font-size: 10.5px; } .tt-cell:nth-child(-n + 5) { /* header row is handled explicitly */ } .tt-head { position: sticky; top: 0; z-index: 2; display: flex; flex-direction: column; gap: 1px; justify-content: center; min-height: 34px; padding: 4px 6px; border-right: 1px solid var(--line-soft); border-bottom: 1px solid var(--line); background: var(--panel-title); color: var(--accent); font-size: 10.5px; letter-spacing: 0.5px; text-transform: uppercase; } .tt-head .date { color: var(--dim); font-size: 9px; letter-spacing: 0.2px; text-transform: none; } .tt-head.today { background: #0e1428; color: var(--fg-bright); } .tt-hour { position: sticky; left: 0; z-index: 1; display: flex; flex-direction: column; justify-content: center; gap: 1px; padding: 4px 5px; border-right: 1px solid var(--line); border-bottom: 1px solid var(--line-soft); background: #050507; color: var(--dim); font-size: 9.5px; font-variant-numeric: tabular-nums; } .tt-hour b { color: var(--accent); font-size: 11px; } .tt-hour.corner { position: sticky; top: 0; z-index: 4; background: var(--panel-title); color: var(--dimmer); text-align: center; } .tt-lesson + .tt-lesson { margin-top: 4px; padding-top: 4px; border-top: 1px dashed var(--line-soft); } .tt-lesson { display: flex; flex-direction: column; gap: 1px; height: 100%; } .tt-subject { color: var(--fg-bright); line-height: 1.25; overflow-wrap: anywhere; } .tt-meta { color: var(--dim); font-size: 9px; line-height: 1.3; } .tt-room { color: var(--cyan); } .tt-flags { display: flex; gap: 3px; flex-wrap: wrap; margin-top: 1px; } .tt-flag { padding: 0 3px; border: 1px solid currentColor; font-size: 7.5px; line-height: 12px; letter-spacing: 0.4px; } .tt-flag.sub { color: var(--amber); } .tt-flag.cancel { color: var(--red); } .tt-flag.extra { color: var(--cyan); } .tt-lesson.cancelled .tt-subject { color: var(--dimmer); text-decoration: line-through; } .tt-lesson.cancelled .tt-meta { color: var(--dimmer); } .tt-empty { color: var(--dimmer); font-size: 10px; text-align: center; padding-top: 10px; } .tt-free { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--dimmer); } /* --------------------------------------------------------------------- tables */ .table-wrap { overflow-x: auto; } .data-table { width: 100%; border-collapse: collapse; font-size: 11.5px; } .data-table th { padding: 5px 7px; border-bottom: 1px solid var(--line); color: var(--dim); font-size: 9px; font-weight: 500; letter-spacing: 1.2px; text-align: left; text-transform: uppercase; white-space: nowrap; } .data-table td { padding: 6px 7px; border-bottom: 1px dashed var(--line-soft); vertical-align: top; } .data-table tbody tr:hover { background: rgba(124, 156, 255, 0.04); } .data-table tbody tr[data-exam] { cursor: pointer; } .data-table tbody tr:last-child td { border-bottom: 0; } .data-table .num { font-variant-numeric: tabular-nums; white-space: nowrap; } .data-table .strong { color: var(--fg-bright); } .data-table .soft { color: var(--dim); } .data-table .content-cell { color: var(--dim); max-width: 480px; } .date-badge { display: inline-block; padding: 1px 5px; border: 1px solid var(--line); color: var(--accent); font-size: 10px; white-space: nowrap; } .date-badge.soon { border-color: var(--amber-dim); color: var(--amber); } .date-badge.urgent { border-color: var(--red-dim); color: var(--red); } .tag { display: inline-block; padding: 0 4px; border: 1px solid currentColor; font-size: 8.5px; line-height: 14px; letter-spacing: 0.4px; white-space: nowrap; } .tag-green { color: var(--accent-mid); } .tag-amber { color: var(--amber); } .tag-red { color: var(--red); } .tag-cyan { color: var(--cyan); } .tag-dim { color: var(--dim); } .tag-violet { color: var(--violet); } /* ----------------------------------------------------------------- attendance */ .att-summary { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; margin-bottom: 10px; } .att-tile { padding: 8px 11px; border: 1px solid var(--line); background: rgba(0, 0, 0, 0.6); } .att-tile .value { color: var(--fg-bright); font-size: 21px; line-height: 1.15; } .att-tile .label { color: var(--dim); font-size: 9px; letter-spacing: 1.1px; text-transform: uppercase; } .att-tile.absent .value { color: var(--red); } .att-tile.late .value { color: var(--amber); } .presence { font-weight: 700; } .presence.yes { color: var(--accent); } .presence.no { color: var(--red); } /* ------------------------------------------------------------------- messages */ .messages-layout { display: grid; grid-template-columns: minmax(250px, 0.85fr) minmax(0, 1.35fr); gap: 10px; align-items: start; } .message-list { max-height: min(66vh, 680px); overflow: auto; } .message-item { display: block; width: 100%; padding: 7px 9px; border: 0; border-bottom: 1px dashed var(--line-soft); background: transparent; color: var(--fg-bright); text-align: left; cursor: pointer; } .message-item:hover { background: rgba(124, 156, 255, 0.05); } .message-item.active { background: rgba(124, 156, 255, 0.14); color: var(--fg-bright); box-shadow: inset 2px 0 0 var(--accent); } .message-item.active .msg-from, .message-item.active .msg-date { color: var(--dim); } .msg-top { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; } .msg-from { color: var(--dim); font-size: 9.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .msg-date { color: var(--dimmer); font-size: 9px; white-space: nowrap; } .msg-subject { margin-top: 1px; font-size: 11.5px; line-height: 1.3; } .msg-unread { color: var(--amber); } .message-item.active .msg-unread { color: var(--amber); } .message-reader { max-height: min(66vh, 680px); overflow: auto; } .reader-head { padding: 10px 12px; border-bottom: 1px solid var(--line); } .reader-subject { margin: 0; color: var(--fg-bright); font-size: 15px; font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; } .reader-meta { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 5px; color: var(--dim); font-size: 10px; } .message-body { padding: 12px; color: #d4d4d8; font-size: 12px; line-height: 1.65; overflow-wrap: anywhere; overflow-x: auto; } .message-body p { margin: 0 0 0.8em; } .message-body a { color: var(--cyan); text-decoration: underline; } .message-body b, .message-body strong { color: var(--fg-bright); } .message-body ul, .message-body ol { margin: 0 0 0.8em; padding-left: 22px; } .message-body img { max-width: 100%; height: auto; border: 1px solid var(--line); } .message-body table { max-width: 100%; border-collapse: collapse; } .message-body td, .message-body th { padding: 3px 6px; border: 1px solid var(--line-soft); } .message-body blockquote { margin: 0 0 0.8em; padding-left: 10px; border-left: 2px solid var(--line); color: var(--dim); } .attachments { padding: 0 12px 12px; } .attachments-title { margin-bottom: 5px; color: var(--dim); font-size: 9px; letter-spacing: 1.4px; text-transform: uppercase; } .attachment { display: flex; align-items: center; gap: 8px; padding: 4px 6px; border: 1px solid var(--line-soft); color: var(--cyan); font-size: 10.5px; text-decoration: none; margin-bottom: 4px; } .attachment:hover { border-color: var(--cyan); background: rgba(126, 232, 255, 0.06); } .attachment .size-hint { margin-left: auto; color: var(--dim); font-size: 9px; } /* -------------------------------------------------------------------- free days */ .split-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; align-items: start; } .free-item { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; padding: 6px 2px; border-bottom: 1px dashed var(--line-soft); } .free-item:last-child { border-bottom: 0; } .free-name { color: var(--accent); } .free-dates { color: var(--dim); font-size: 10px; white-space: nowrap; font-variant-numeric: tabular-nums; } .conf-item { padding: 6px 2px; border-bottom: 1px dashed var(--line-soft); } .conf-item:last-child { border-bottom: 0; } .conf-name { color: var(--fg-bright); } .conf-meta { color: var(--dim); font-size: 10px; margin-top: 1px; } /* ---------------------------------------------------------------- empty/loading */ .empty { padding: 26px 12px; color: var(--dimmer); text-align: center; font-size: 11px; letter-spacing: 1px; } .empty::before { content: "[ "; } .empty::after { content: " ]"; } .loading { display: flex; align-items: center; gap: 10px; padding: 30px 8px; color: var(--dim); font-size: 11.5px; letter-spacing: 0.5px; } .spinner { color: var(--accent); font-size: 15px; } .error-panel { max-width: 640px; margin: 30px auto; border: 1px solid var(--red-dim); } .error-panel .panel-title { background: #18070b; border-bottom-color: var(--red-dim); color: var(--red); } .error-message { padding: 14px; color: #ffb3b3; font-size: 12px; line-height: 1.6; overflow-wrap: anywhere; } .error-actions { padding: 0 14px 14px; } /* --------------------------------------------------------------------- command */ .command { flex: 0 0 auto; border-top: 1px solid var(--line); background: #000000; } .command-line { display: flex; align-items: center; gap: 7px; min-height: 29px; padding: 2px 10px; color: var(--dim); font-size: 11.5px; overflow: hidden; } .prompt { color: var(--accent-mid); white-space: nowrap; } .command-display { color: var(--fg-bright); white-space: nowrap; } .command-input { flex: 1; min-width: 120px; padding: 0; border: 0; outline: 0; background: transparent; color: var(--fg-bright); caret-color: var(--accent); } .command-hint { margin-left: auto; color: var(--dimmer); font-size: 9.5px; white-space: nowrap; } .command-line.command-mode { background: #08080c; } .statusbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 21px; padding: 0 10px; background: #050508; border-top: 1px solid var(--line); color: var(--dim); font-size: 9.5px; font-weight: 600; letter-spacing: 0.3px; } .status-left { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .status-left.error { color: var(--red); } .status-left.ok { color: var(--accent); } .status-keys { display: flex; align-items: center; gap: 3px; white-space: nowrap; opacity: 0.78; } .status-keys kbd { border-color: var(--line); background: rgba(0, 0, 0, 0.3); color: var(--dim); } .status-right { white-space: nowrap; opacity: 0.7; } kbd { display: inline-block; min-width: 13px; padding: 0 3px; border: 1px solid var(--line); color: var(--dim); font-family: inherit; font-size: 9px; line-height: 14px; text-align: center; } /* --------------------------------------------------------------------- toasts */ .toasts { position: fixed; right: 22px; bottom: 56px; z-index: 120; display: flex; flex-direction: column; gap: 6px; max-width: min(380px, calc(100vw - 30px)); pointer-events: none; } .toast { padding: 7px 10px; border: 1px solid var(--line); background: rgba(8, 8, 10, 0.96); color: var(--accent); font-size: 11px; line-height: 1.45; box-shadow: 0 4px 18px rgba(0, 0, 0, 0.5); animation: toast-in 0.16s ease-out; } .toast.ok { border-color: var(--accent-mid); } .toast.err { border-color: var(--red-dim); color: #ffb3b3; } .toast.warn { border-color: var(--amber-dim); color: var(--amber); } .toast .toast-prefix { margin-right: 5px; font-weight: 700; } @keyframes toast-in { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: translateY(0); } } /* --------------------------------------------------------------------- modal */ .modal-root { position: fixed; inset: 0; z-index: 110; display: flex; align-items: center; justify-content: center; padding: 20px; } .modal-backdrop { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.72); backdrop-filter: blur(1px); } .modal-box { position: relative; width: min(660px, 100%); max-height: min(82vh, 720px); display: flex; flex-direction: column; border: 1px solid var(--accent-mid); background: #000000; box-shadow: 0 0 0 1px #000, 0 0 40px rgba(124, 156, 255, 0.12), 0 20px 80px rgba(0, 0, 0, 0.65); outline: none; animation: modal-in 0.13s ease-out; } @keyframes modal-in { from { opacity: 0; transform: scale(0.985); } to { opacity: 1; transform: scale(1); } } .modal-title { flex: 0 0 auto; padding: 4px 10px; background: #0a0a0d; color: var(--accent); border-bottom: 1px solid var(--line); font-size: 10px; font-weight: 700; letter-spacing: 1.7px; text-transform: uppercase; } .modal-body { flex: 1 1 auto; padding: 14px; overflow: auto; color: #d4d4d8; font-size: 12px; line-height: 1.65; } .modal-body p { margin: 0 0 0.8em; } .modal-body p:last-child { margin-bottom: 0; } .modal-actions { flex: 0 0 auto; display: flex; justify-content: flex-end; gap: 8px; padding: 0 14px 14px; flex-wrap: wrap; } .modal-actions .btn { min-width: 92px; } .detail-grid { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 5px 14px; margin: 0; } .detail-grid dt { color: var(--dim); font-size: 10px; letter-spacing: 0.7px; text-transform: uppercase; } .detail-grid dd { margin: 0; color: var(--fg-bright); overflow-wrap: anywhere; } .detail-comment { margin-top: 14px; padding: 8px 10px; border-left: 2px solid var(--line); color: var(--dim); font-style: italic; } .help-grid { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 4px 18px; margin: 0; } .help-grid dt { color: var(--accent); white-space: nowrap; } .help-grid dd { margin: 0; color: var(--dim); } .help-grid code, .help-section + p code { color: var(--cyan); } .help-section { margin: 16px 0 7px; padding-bottom: 3px; border-bottom: 1px solid var(--line-soft); color: var(--accent); font-size: 9.5px; letter-spacing: 1.5px; text-transform: uppercase; } .help-section:first-child { margin-top: 0; } /* ------------------------------------------------------------------ scrollbars */ * { scrollbar-width: thin; scrollbar-color: var(--line) transparent; } ::-webkit-scrollbar { width: 9px; height: 9px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: #26262c; border: 2px solid #000000; } ::-webkit-scrollbar-thumb:hover { background: #4f7cff; } /* ------------------------------------------------------------------- responsive */ @media (max-width: 1120px) { .dash-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .dash-grid .span-2 { grid-column: span 2; } .dash-grid .identity-panel, .dash-grid .counters-panel, .dash-grid .today-panel, .dash-grid .freedays-panel { grid-column: span 2; } .grades-grid { grid-template-columns: 1fr; } } @media (max-width: 900px) { body { padding: 0; } .crt, .terminal { height: 100dvh; } .terminal { border: 0; } .app-grid { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr); } .sidebar { flex-direction: row; align-items: center; gap: 2px; padding: 4px; border-right: 0; border-bottom: 1px solid var(--line); overflow-x: auto; overflow-y: hidden; } .side-head, .side-sep, .side-spacer, .side-user, .side-foot, .nav-muted { display: none; } .nav-item { flex: 0 0 auto; width: auto; padding: 4px 7px; } .nav-label { font-size: 10.5px; } .messages-layout { grid-template-columns: 1fr; } .message-list, .message-reader { max-height: 48vh; } } @media (max-width: 720px) { .login-grid { grid-template-columns: 1fr; } .login-wrap { padding-top: 24px; } .logo-sub { margin-bottom: 20px; letter-spacing: 1.4px; } .login-hint { display: none; } .titlebar-sub, .titlebar-date { display: none; } .dash-grid, .split-2, .att-summary { grid-template-columns: 1fr; } .dash-grid .span-2, .dash-grid .identity-panel, .dash-grid .counters-panel, .dash-grid .today-panel, .dash-grid .freedays-panel { grid-column: span 1; } .stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .stat:nth-child(2) { border-right: 0; } .stat:nth-child(-n + 2) { border-bottom: 1px solid var(--line-soft); } .command-hint, .status-keys { display: none; } .view { padding: 9px; } .view-meta { display: none; } .att-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; } }