/* The six page views' own styles, in the components layer. Loaded AFTER css/matrix.css and css/detail.css
   so that — inside that one layer — they keep the last word over the shared component chrome, exactly as the
   five legacy sheets they replace did when they were unlayered (Phase 3e.4.3.1). Order inside matters: the blocks
   below follow the old load order styles → live-status → ui-hardening → compact → legacy-overrides. */
@layer views {
/* ===================== moved from styles.css (Phase 3e.4.3.1) ===================== */
.side-groups{display:grid;gap:4px}.eyebrow{font-size:var(--font-size-caption);color:var(--muted-text);letter-spacing:.08em;margin-bottom:6px}.stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:13px;margin-bottom:18px}.stat{background:var(--surface-panel);border:1px solid var(--line-border);border-radius:var(--radius-lg);padding:15px 18px;display:flex;align-items:center;justify-content:space-between;gap:10px}.stat-label{font-size:var(--font-size-label);color:var(--muted-text);line-height:1.65}.stat strong{font-size:1.812rem;font-weight:700;letter-spacing:-.04em;font-variant-numeric:tabular-nums}.stat .accent{color:var(--blue-text)}.table-scroll{width:100%;overflow:auto;overscroll-behavior-x:contain}table{border-collapse:separate;border-spacing:0;width:100%;table-layout:fixed;text-align:left;font-size:var(--font-size-body-sm)}table.schedule{min-width:1030px}.schedule th,.schedule td{border-right:1px solid var(--line-border);border-bottom:1px solid var(--line-border);vertical-align:top}.schedule th:last-child,.schedule td:last-child{border-right:0}.schedule tr:last-child td,.schedule tr:last-child th{border-bottom:0}.schedule thead th{background:var(--c-f9fafc-bg);padding:13px 9px;font-weight:600;color:var(--c-3a4963-text);text-align:center;vertical-align:middle}.schedule thead th:first-child{width:113px;text-align:left;padding-left:16px}.schedule thead th small{display:block;font-size:var(--font-size-caption);font-weight:400;white-space:nowrap}.schedule tbody th{width:113px;background:var(--surface-panel);position:sticky;left:0;z-index:1;padding:16px 10px 13px 15px;vertical-align:middle}.schedule tbody td{padding:6px;background:var(--surface-panel)}.schedule thead th.focus-day{background:var(--c-edf3ff-bg);color:var(--blue-text)}.roomlink{border:0;background:transparent;font-size:var(--font-size-body-sm);font-weight:650;padding:0;text-align:left;color:var(--ink-text);line-height:1.5}.roomlink:hover{color:var(--blue-text);background:transparent}.roomlink small{display:block;font-weight:400;font-size:var(--font-size-caption);line-height:1.8}.slot-label{font-weight:650;font-size:var(--font-size-body-sm)}.slot-label small{display:block;font-size:var(--font-size-caption);font-weight:400;white-space:nowrap;margin-top:4px}.footnote{padding:13px 19px;background:var(--c-fcfdff-bg);border-top:1px solid var(--line-border);font-size:var(--font-size-caption);color:var(--muted-text);line-height:1.8}.free-form .field{flex:1;min-width:130px;max-width:210px}dialog{border:1px solid var(--line-border);border-radius:16px;padding:0;width:min(710px,calc(100% - 24px));max-height:90vh;box-shadow:0 20px 80px color-mix(in srgb, var(--c-152945-border) 20%, transparent);color:var(--ink-text)}dialog::backdrop{background:color-mix(in srgb, var(--c-17243d-bg) 43.9%, transparent);backdrop-filter:blur(2px)}dialog.wide{width:min(1180px,calc(100% - 24px))}.dialog-head{position:sticky;top:0;background:var(--surface-panel);z-index:3;display:flex;gap:15px;justify-content:space-between;align-items:center;padding:19px 22px;border-bottom:1px solid var(--line-border)}.dialog-head h2{font-size:var(--font-size-section)}.dialog-head button{padding:3px 10px;font-size:1.438rem}.dialog-body{padding:22px;font-size:var(--font-size-body-sm);line-height:1.8}.dialog-body .event{margin:8px 0}.detail-grid{display:grid;grid-template-columns:90px 1fr;gap:12px 17px;margin:17px 0}.detail-grid dt{color:var(--muted-text)}.detail-grid dd{margin:0;overflow-wrap:anywhere}.dialog-body details{margin-top:15px}.dialog-body summary{cursor:pointer;color:var(--blue-text)}.dialog-body ul{padding-left:20px}.dialog-body iframe{width:100%;height:67vh;border:1px solid var(--line-border)}.toast{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);background:var(--ink-bg);color:#ffffff;padding:10px 17px;border-radius:9px;font-size:var(--font-size-body-sm);z-index:10;max-width:calc(100vw - 30px)}noscript{display:block;padding:20px;background:var(--c-fff4df-bg);color:var(--c-80521b-text)}
@media(min-width:1500px){table.schedule{min-width:1110px}.event{padding:11px}.event .event-title{font-size:0.9375rem}.schedule tbody td{padding:8px}}
@media(max-width:1120px){.stat{padding:13px}.stat strong{font-size:1.562rem}}
@media(max-width:900px),(max-height:480px) and (orientation:landscape){h1{font-size:1.438rem}.eyebrow{font-size:0.6875rem;letter-spacing:0}.field{min-width:0}.stats{grid-template-columns:repeat(2,minmax(0,1fr));gap:9px;margin-bottom:13px}.stat{padding:10px 13px}.stat-label{font-size:var(--font-size-caption)}.stat strong{font-size:1.562rem}.free-form .field{min-width:110px;max-width:none}.dialog-body{padding:16px}.dialog-head{padding:15px 16px}.detail-grid{grid-template-columns:75px 1fr;gap:10px}.footnote{padding:11px 14px}.banner{font-size:var(--font-size-label)}.table-scroll{background:linear-gradient(90deg,var(--surface-panel) 30%,color-mix(in srgb, var(--surface-panel) 0%, transparent)),linear-gradient(90deg,color-mix(in srgb, var(--surface-panel) 0%, transparent),var(--surface-panel) 70%) 100% 0,radial-gradient(farthest-side at 0 50%,color-mix(in srgb, var(--c-243b62-bg) 13.3%, transparent),color-mix(in srgb, var(--c-000000-bg) 0%, transparent)),radial-gradient(farthest-side at 100% 50%,color-mix(in srgb, var(--c-243b62-bg) 13.3%, transparent),color-mix(in srgb, var(--c-000000-bg) 0%, transparent)) 100% 0;background-repeat:no-repeat;background-size:25px 100%,25px 100%,9px 100%,9px 100%;background-attachment:local,local,scroll,scroll}}
@media(prefers-reduced-motion:reduce){*{transition:none!important;scroll-behavior:auto!important}}

/* Mobile layouts use the same events and interval calculations as desktop. */
.mobile-schedule{display:none}
@media(max-width:900px),(max-height:480px) and (orientation:landscape){
 .schedule-desktop{display:none}.mobile-schedule{display:grid;gap:12px;padding:14px}
 .mobile-room{border:1px solid var(--line-border);border-radius:var(--radius-lg);overflow:hidden;background:var(--surface-panel);min-width:0}
 .mobile-room-header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:13px 14px;background:var(--c-fafbfd-bg)}
 .mobile-room-header .roomlink{min-height:44px;font-size:var(--font-size-body);display:flex;flex-direction:column;justify-content:center}
 .mobile-room-header .roomlink small{font-size:var(--font-size-caption)}.mobile-room-header .tag{flex:none}
 .mobile-agenda{padding:12px}.mobile-agenda .event{padding:12px;margin-bottom:8px;border-left-width:4px}
 .mobile-agenda .event-title{font-size:var(--font-size-body)}.mobile-agenda .event-time{font-size:var(--font-size-body-sm);margin-top:6px}
 .mobile-agenda .event-meta{font-size:var(--font-size-label);line-height:1.7}.mobile-agenda .event .small{font-size:var(--font-size-label)}
 .mobile-empty{padding:12px 14px;color:var(--green-text);font-size:var(--font-size-body-sm);background:var(--c-f7fbf8-bg)}
 .mobile-empty.unknown{color:var(--muted-text);background:var(--c-f8f9fb-bg)}
 .mobile-gaps{border-top:1px solid var(--line-border);font-size:var(--font-size-label);color:var(--muted-text);padding:0 14px}
 .mobile-gaps summary{cursor:pointer;min-height:44px;display:flex;align-items:center;gap:8px;list-style:none}
 .mobile-gaps summary:before{content:'+';font-size:var(--font-size-body-lg);color:var(--green-text)}.mobile-gaps[open] summary:before{content:'−'}
 .mobile-gaps .ranges{margin:0 0 13px}.mobile-gaps .range{font-size:var(--font-size-body-sm);padding:3px 7px}
 .mobile-week-days{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:7px;padding:12px}
 .mobile-day-button{display:flex;align-items:center;justify-content:center;flex-direction:column;gap:4px;min-height:83px;padding:8px 3px;background:var(--c-f7fbf8-bg);border-color:var(--c-dbe9e1-border);color:var(--green-text);font-size:var(--font-size-label)}
 .mobile-day-button strong{font-size:var(--font-size-body-sm)}.mobile-day-button small{color:inherit;font-size:var(--font-size-caption);opacity:.9}
 .mobile-day-button.busy{background:var(--softblue-bg);border-color:var(--c-d6e2fa-border);color:var(--c-315a98-text)}
 .mobile-day-button.makeup{background:var(--softred-bg);border-color:var(--c-f0cbd3-border);color:var(--red-text)}
 .mobile-day-button.unknown{background:var(--c-f5f6f8-bg);color:var(--muted-text);border-color:var(--line-border)}
 .mobile-day-button.selected{outline:2px solid var(--blue-border);outline-offset:0}
 .mobile-day-button.matched{box-shadow:inset 0 0 0 2px var(--c-83a3e5-border)}
 .mobile-day-details{border:1px solid var(--line-border);border-radius:11px;overflow:hidden}
 .mobile-day-details>summary{display:flex;align-items:center;justify-content:space-between;gap:12px;cursor:pointer;list-style:none;padding:14px;min-height:66px;background:var(--c-f9fafc-bg)}
 .mobile-day-details>summary::-webkit-details-marker,.mobile-gaps>summary::-webkit-details-marker{display:none}
 .mobile-day-details>summary strong{font-size:var(--font-size-body)}.mobile-day-details>summary small{display:block;font-size:var(--font-size-label)}
 .mobile-day-summary{display:flex;align-items:center;gap:9px;font-size:var(--font-size-body-sm);color:var(--muted-text)}
 .mobile-day-summary:after{content:'⌄';font-size:1.312rem}.mobile-day-details[open] .mobile-day-summary:after{content:'⌃'}
 .mobile-day-details.selected{border-color:var(--c-adc3ed-border)}.mobile-day-details.selected>summary{background:var(--softblue-bg)}
 .mobile-card-note{font-size:var(--font-size-caption);color:var(--muted-text);padding:0 14px 12px}
}
@media(max-width:900px),(max-height:480px) and (orientation:landscape){
 body{padding-bottom:env(safe-area-inset-bottom);-webkit-text-size-adjust:100%}

 h1{font-size:1.438rem}.eyebrow{font-size:var(--font-size-caption);letter-spacing:0}

 .stats{gap:8px}.stat{padding:11px 12px;min-width:0}.stat strong{font-size:1.562rem;white-space:nowrap}.stat-label small{font-size:var(--font-size-caption)}

 .panel-actions button,.source-buttons button,.room-card button,.exam-card button,.switch-row button{min-height:44px;font-size:var(--font-size-body-sm)}

 .mobile-schedule{padding:11px;gap:11px}.footnote{font-size:var(--font-size-caption);overflow-wrap:anywhere}
 .free-form .field{min-width:0;max-width:none;width:100%}
 .detail-grid{font-size:0.9375rem}
 dialog{width:calc(100% - 16px);max-height:calc(100vh - 24px);max-height:calc(100dvh - 24px);margin:auto;border-radius:var(--radius-panel);overscroll-behavior:contain}
 dialog.wide{width:calc(100% - 16px)}.dialog-head{padding:12px 14px}.dialog-head h2{font-size:var(--font-size-body-lg)}
 .dialog-head button{min-width:44px;min-height:44px}.dialog-body{font-size:0.9375rem;padding:15px;overflow-wrap:anywhere}
 .dialog-body .switch-row button{flex:1;min-width:120px}.dialog-body .range{font-size:var(--font-size-body-sm);padding:4px 7px}
 .dialog-body summary{min-height:44px;padding:8px 0}.dialog-body iframe{height:58vh;height:58dvh}
 .toast{bottom:calc(83px + env(safe-area-inset-bottom));font-size:var(--font-size-body-sm);width:max-content;max-width:calc(100% - 24px)}

}
@media(max-width:370px){.mobile-week-days{gap:5px;padding:9px}.mobile-day-button{font-size:var(--font-size-caption)}.stats{grid-template-columns:1fr 1fr}.stat{padding:9px}.stat strong{font-size:1.438rem}.stat-label{font-size:var(--font-size-caption)}}

.duty-brief>summary{cursor:pointer;color:var(--blue-text);font-size:var(--font-size-body-sm);min-height:44px;padding:10px 0}
@media(max-width:900px),(max-height:480px) and (orientation:landscape){.duty-brief>summary{font-size:var(--font-size-body-sm)}.mobile-room-header .room-label-stack{flex:1}.mobile-room-header .roomlink{min-height:40px}}

.time-first thead .roomlink{font-size:var(--font-size-body)}.time-first .roomlink small{font-size:var(--font-size-label);color:var(--muted-text)}

/* Reflow and zoom: keep overflow inside data tables, never on the page. */
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
.panel,.panel-head>div,.field,.stat-label,.dialog-head h2{min-width:0}
.panel-head,.panel-actions,.room-card-head,.exam-top{flex-wrap:wrap}
.panel-actions{max-width:100%}
.panel-actions button,.source-buttons button,.tag{white-space:normal;overflow-wrap:anywhere}
.panel-head h2,.duty-card h3,.day-duty-card h3{overflow-wrap:anywhere}
.field select,.field input{height:auto;min-height:2.75rem}

.field input,.field select{font-size:var(--font-size-body);max-width:100%}

.stats{grid-template-columns:repeat(4,minmax(0,1fr))}
.stat{flex-wrap:wrap;align-content:center}.stat strong{line-height:1.2}
.table-scroll{max-width:100%}
.schedule-desktop{max-height:70vh;max-height:70dvh;scrollbar-gutter:stable}
.schedule thead th{position:sticky;top:0;z-index:2}
.schedule thead th:first-child{left:0;z-index:4}
.schedule tbody th{z-index:1;box-shadow:1px 0 var(--line-border)}
.time-first thead .roomlink{font-size:.9375rem}
.time-first .event{padding:8px}
.table-hint{padding:8px 20px;font-size:.8125rem;color:var(--muted-text);background:var(--c-f9fafc-bg);border-bottom:1px solid var(--line-border)}
dialog{max-width:calc(100% - 24px);max-height:calc(100dvh - 24px);overflow:auto}
.dialog-head{align-items:flex-start}.dialog-head button{flex:none;min-width:44px;min-height:44px}
.detail-grid{grid-template-columns:minmax(0,5.5rem) minmax(0,1fr)}
@media(min-width:901px) and (min-height:481px) and (max-width:1200px){
 .stats{grid-template-columns:repeat(2,minmax(0,1fr))}

}
@media(max-width:900px),(max-height:480px) and (orientation:landscape){

 .stats{grid-template-columns:repeat(2,minmax(0,1fr))}

 .toast{bottom:calc(98px + env(safe-area-inset-bottom))}
 .mobile-room-header,.mobile-day-details>summary{flex-wrap:wrap}
 .mobile-room-header .tag{flex-shrink:1}
 .table-hint{display:none}
}
@media(max-width:400px){

 .mobile-week-days{grid-template-columns:repeat(3,minmax(0,1fr))}
 .panel-actions{width:100%}.panel-actions button{flex:1 1 6rem}

 .dialog-body .switch-row button{min-width:0;flex:1 1 100%}
 .detail-grid{grid-template-columns:minmax(0,1fr);gap:3px}.detail-grid dd{margin-bottom:10px}
}

/* The timetable is a two-axis working surface on phones and computers. */

 .mobile-schedule{display:grid;gap:12px;padding:14px}
 .mobile-room{border:1px solid var(--line-border);border-radius:var(--radius-lg);overflow:hidden;background:var(--surface-panel);min-width:0}
 .mobile-room-header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:13px 14px;background:var(--c-fafbfd-bg)}
 .mobile-room-header .roomlink{min-height:44px;font-size:var(--font-size-body);display:flex;flex-direction:column;justify-content:center}
 .mobile-room-header .roomlink small{font-size:var(--font-size-caption)}.mobile-room-header .tag{flex:none}
 .mobile-agenda{padding:12px}.mobile-agenda .event{padding:12px;margin-bottom:8px;border-left-width:4px}
 .mobile-agenda .event-title{font-size:var(--font-size-body)}.mobile-agenda .event-time{font-size:var(--font-size-body-sm);margin-top:6px}
 .mobile-agenda .event-meta{font-size:var(--font-size-label);line-height:1.7}.mobile-agenda .event .small{font-size:var(--font-size-label)}
 .mobile-empty{padding:12px 14px;color:var(--green-text);font-size:var(--font-size-body-sm);background:var(--c-f7fbf8-bg)}
 .mobile-empty.unknown{color:var(--muted-text);background:var(--c-f8f9fb-bg)}
 .mobile-gaps{border-top:1px solid var(--line-border);font-size:var(--font-size-label);color:var(--muted-text);padding:0 14px}
 .mobile-gaps summary{cursor:pointer;min-height:44px;display:flex;align-items:center;gap:8px;list-style:none}
 .mobile-gaps summary:before{content:'+';font-size:var(--font-size-body-lg);color:var(--green-text)}.mobile-gaps[open] summary:before{content:'−'}
 .mobile-gaps .ranges{margin:0 0 13px}.mobile-gaps .range{font-size:var(--font-size-body-sm);padding:3px 7px}
 .mobile-week-days{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:7px;padding:12px}
 .mobile-day-button{display:flex;align-items:center;justify-content:center;flex-direction:column;gap:4px;min-height:83px;padding:8px 3px;background:var(--c-f7fbf8-bg);border-color:var(--c-dbe9e1-border);color:var(--green-text);font-size:var(--font-size-label)}
 .mobile-day-button strong{font-size:var(--font-size-body-sm)}.mobile-day-button small{color:inherit;font-size:var(--font-size-caption);opacity:.9}
 .mobile-day-button.busy{background:var(--softblue-bg);border-color:var(--c-d6e2fa-border);color:var(--c-315a98-text)}
 .mobile-day-button.makeup{background:var(--softred-bg);border-color:var(--c-f0cbd3-border);color:var(--red-text)}
 .mobile-day-button.unknown{background:var(--c-f5f6f8-bg);color:var(--muted-text);border-color:var(--line-border)}
 .mobile-day-button.selected{outline:2px solid var(--blue-border);outline-offset:0}
 .mobile-day-button.matched{box-shadow:inset 0 0 0 2px var(--c-83a3e5-border)}
 .mobile-day-details{border:1px solid var(--line-border);border-radius:11px;overflow:hidden}
 .mobile-day-details>summary{display:flex;align-items:center;justify-content:space-between;gap:12px;cursor:pointer;list-style:none;padding:14px;min-height:66px;background:var(--c-f9fafc-bg)}
 .mobile-day-details>summary::-webkit-details-marker,.mobile-gaps>summary::-webkit-details-marker{display:none}
 .mobile-day-details>summary strong{font-size:var(--font-size-body)}.mobile-day-details>summary small{display:block;font-size:var(--font-size-label)}
 .mobile-day-summary{display:flex;align-items:center;gap:9px;font-size:var(--font-size-body-sm);color:var(--muted-text)}
 .mobile-day-summary:after{content:'⌄';font-size:1.312rem}.mobile-day-details[open] .mobile-day-summary:after{content:'⌃'}
 .mobile-day-details.selected{border-color:var(--c-adc3ed-border)}.mobile-day-details.selected>summary{background:var(--softblue-bg)}
 .mobile-card-note{font-size:var(--font-size-caption);color:var(--muted-text);padding:0 14px 12px}

.schedule-panel{--table-scale:1}

.table-scale-controls{display:flex;align-items:center;gap:.35rem;min-width:0}

.table-scale-controls label{font-size:.8125rem;color:var(--muted-text);margin-right:.25rem}
.table-scale-controls select{width:5.2rem;background:var(--surface-panel);border:1px solid var(--line-border);padding:.4rem;font-size:var(--font-size-body);color:var(--ink-text)}
.table-scale-controls button{min-width:2.75rem;padding:.35rem;font-size:1.2rem;line-height:1}
.schedule-panel .mobile-schedule{display:none}
.schedule-panel[data-schedule-layout="table"] .schedule-desktop{display:block}
.schedule-panel[data-schedule-layout="cards"] .mobile-schedule{display:grid}
.schedule-panel[data-schedule-layout="cards"] .schedule-desktop,
.schedule-panel[data-schedule-layout="cards"] .table-hint,
.schedule-panel[data-schedule-layout="cards"] .table-scale-controls{display:none}
.schedule-panel .table-hint{display:block;font-size:.8125rem;padding:.5rem 1rem}
.schedule-panel .schedule-desktop{overflow:auto;max-height:72vh;max-height:72dvh;scrollbar-gutter:stable;isolation:isolate;-webkit-overflow-scrolling:touch;touch-action:pan-x pan-y pinch-zoom}
/* All table typography and geometry share one font-relative scale. No
   transform or CSS zoom: sticky cells and hit targets use actual layout sizes. */
.schedule-panel table.schedule{font-size:calc(.875rem * var(--table-scale));width:100%;min-width:var(--table-width,80.8em);line-height:1.5}
.schedule-panel table.schedule thead th{font-size:1em;padding:.75em .65em;position:sticky;top:0;z-index:2}
.schedule-panel table.schedule thead th:first-child,
.schedule-panel table.schedule tbody th{width:8em;padding:.8em .65em;left:0}
.schedule-panel table.schedule thead th:first-child{z-index:4}
.schedule-panel table.schedule tbody th{position:sticky;z-index:1}
.schedule-panel .schedule tbody td{padding:.4em}
.schedule-panel .schedule .event{font-size:1em;padding:.65em .6em;margin-bottom:.35em;border-left-width:.22em;border-radius:.45em;line-height:1.5}
.schedule-panel .schedule .event:last-child{margin-bottom:0}
.schedule-panel .schedule .event-title{font-size:1em}
.schedule-panel .schedule .event-time{font-size:.86em;margin-top:.3em;white-space:normal}
.schedule-panel .schedule .event-meta{font-size:.86em;margin-top:.2em}
.schedule-panel .schedule .roomlink{font-size:1.07em;line-height:1.5}
.schedule-panel .schedule .roomlink small{font-size:.85em;line-height:1.7}
.schedule-panel .schedule .duty-link{font-size:.86em;min-height:0;margin-top:.2em;padding:.3em 0}
.schedule-panel .schedule .slot-label{font-size:1em;white-space:normal}
.schedule-panel .schedule .slot-label small,
.schedule-panel .schedule thead th small{font-size:.86em;margin-top:.3em;white-space:normal}
.schedule-panel .schedule .small,.schedule-panel .schedule .tag{font-size:.86em}
.schedule-panel .schedule .tag{padding:.1em .4em;border-radius:.35em}
.schedule-panel .schedule .empty-cell{font-size:.93em;min-height:6em;gap:.15em;border-radius:.4em}
.schedule-panel .schedule .week-summary{font-size:1em;min-height:6em;padding:.7em .4em;border-radius:.4em}
.schedule-panel .schedule .week-summary strong{font-size:1em;margin-bottom:.5em}
.schedule-panel .schedule .week-summary small{font-size:.86em;margin-top:.35em}
.schedule-panel .schedule .mini-blocks{gap:.22em;max-width:9.6em}
.schedule-panel .schedule .mini-block{height:.43em;border-radius:.14em}
@media(min-width:901px) and (min-height:481px){
 .schedule-panel[data-schedule-layout="cards"] .mobile-schedule{grid-template-columns:repeat(auto-fit,minmax(min(100%,22rem),1fr));align-items:start}
}
@media(max-width:900px),(max-height:480px) and (orientation:landscape){

 .table-scale-controls{margin-left:auto}
 .schedule-panel .schedule-desktop{max-height:68vh;max-height:68dvh}
 .schedule-panel .table-hint{padding:.5rem .75rem;line-height:1.6}
 .stat-label small,.stat-label br{display:none}.stat{padding:.6rem .75rem}
 .schedule-panel .panel-head{padding:.75rem}.schedule-panel .legend{padding:.6rem .75rem}
}
@media(max-width:380px){

 .table-scale-controls{justify-content:flex-end;width:100%}
}

/* Cloudflare D1 boot error */
.boot-error{max-width:760px;margin:10vh auto;padding:28px;background:var(--surface-panel);border:1px solid var(--line-border);border-radius:18px;box-shadow:0 18px 45px rgba(23,36,61,.08)}.boot-error h1{margin-bottom:12px}.boot-error code{background:var(--c-f4f6fa-bg);padding:.15em .4em;border-radius:5px}.boot-error pre{white-space:pre-wrap;background:var(--c-f6f8fb-bg);padding:14px;border-radius:10px;overflow:auto}


/* ===================== moved from live-status.css (Phase 3e.4.3.1) ===================== */
/* "Happening now": one marker for the matrix, the classic table and the cards. The matrix fills the live cells solid
   and washes the current column; the classic table and cards get a left bar and a solid "进行中" pill. The accent is
   teal because nothing else uses it (course blue, exam amber, makeup red, software purple, free green). */
.event.is-live{position:relative;z-index:1;border-left-color:var(--live-border)!important;background-image:linear-gradient(90deg,var(--live-band-bg),transparent 70%)}
.event.is-live .event-time [data-live-date]:not(:empty){display:inline-flex;align-items:center;gap:5px;margin-left:6px;padding:1px 9px 1px 7px;border-radius:var(--radius-pill);background:var(--cell-live-bg);color:var(--cell-live-fg);font-weight:700;line-height:1.45}
.event.is-live .event-time [data-live-date]:not(:empty)::before{content:"";flex:none;width:7px;height:7px;border-radius:50%;background:currentColor;animation:live-blink 1.8s ease-in-out infinite}
.swatch.live{background:var(--cell-live-bg);border-color:var(--cell-live-bg)}
@keyframes live-blink{50%{opacity:.3}}
@media (prefers-reduced-motion:reduce){.event.is-live .event-time [data-live-date]:not(:empty)::before{animation:none}}
@media (prefers-contrast:more){.event.is-live{border-left-width:6px}}
/* Classic day table: the row of the period that is happening now. */
.schedule tbody th.is-now{background:var(--live-soft-bg);box-shadow:inset 4px 0 0 var(--live-border)}
.schedule tbody th.is-now .slot-label,.schedule tbody th.is-now .slot-label small{color:var(--live-text)}


/* ===================== moved from ui-hardening.css (Phase 3e.4.3.1) ===================== */
/* Layout hardening layer: loaded after the main styles so it can safely fix
   viewport, overflow and stacking edge cases without changing the visual theme. */
html{min-width:320px;-webkit-text-size-adjust:100%;text-size-adjust:100%}
body{min-width:0}
.panel,.panel-head,.panel-head>div,.table-scroll,#view,.field{min-width:0}

.panel,.schedule-panel{isolation:isolate}
.schedule-panel .schedule-desktop{position:relative;max-width:100%;isolation:isolate;overscroll-behavior:contain}
.schedule-panel table.schedule thead th{z-index:var(--ui-layer-sticky);background-clip:padding-box}
.schedule-panel table.schedule tbody th{z-index:calc(var(--ui-layer-sticky) - 5);background:var(--surface-panel);background-clip:padding-box}
.schedule-panel table.schedule thead th:first-child{z-index:calc(var(--ui-layer-sticky) + 5)}
.event.is-live{z-index:auto}
.table-scroll{max-width:100%;scrollbar-gutter:stable}
dialog{max-width:calc(100vw - 24px);max-height:calc(100dvh - 24px);overflow:hidden}
dialog .dialog-head{z-index:3;flex:none}
dialog .dialog-body{max-height:calc(100dvh - 84px);overflow:auto;overscroll-behavior:contain}
.toast{z-index:var(--ui-layer-toast);pointer-events:none}
img,iframe{max-width:100%}

@media(max-width:900px),(max-height:480px) and (orientation:landscape){
  body{overflow-wrap:anywhere}

  .stats{min-width:0}

  .panel-head{align-items:flex-start}
  .panel-actions{min-width:0;flex-wrap:wrap;justify-content:flex-end}
  .mobile-room-header,.room-label-stack,.mobile-agenda,.mobile-day-details{min-width:0}
  .mobile-room-header>*{min-width:0}
  dialog{width:min(710px,calc(100vw - 16px));max-width:calc(100vw - 16px);max-height:calc(100dvh - 16px)}
  dialog .dialog-body{max-height:calc(100dvh - 74px)}
}

@media(max-width:520px){

  .stats{gap:7px}
  .panel{border-radius:var(--radius-lg)}
  .mobile-schedule{padding-left:10px;padding-right:10px}
}

@media(max-width:360px){
  html{min-width:280px}

  .stat{min-width:0}
  .stat strong{font-size:1.3rem}
}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{scroll-behavior:auto!important;transition:none!important;animation:none!important}
}

/* Software install styling */
.event.software{background:var(--c-f5f0ff-bg);color:var(--c-581c87-text);border-left-color:var(--c-a855f7-border)}
.event.software:hover{background:var(--c-ede5fd-bg)}

.swatch.software{background:var(--c-ede9fe-bg);border-color:var(--c-c4b5fd-border)}

/* Software install schedule reminder for Today view */
.software-reminder-bar{
  padding:12px 18px;
  border-bottom:1px solid var(--line-border);
  background:var(--c-faf7fc-bg);
  display:flex;
  flex-direction:column;
  gap:10px;
}
.software-reminder-bar.active{
  background:linear-gradient(180deg, var(--c-fdfaff-bg) 0%, var(--c-faf5ff-bg) 100%);
  border-bottom:1px solid var(--c-e9d5ff-border);
}
.software-reminder-bar.empty{
  background:var(--c-fafafd-bg);
  padding:9px 18px;
}
.software-reminder-head{
  display:flex;
  align-items:center;
  justify-content:space-between;
  flex-wrap:wrap;
  gap:8px;
}
.software-reminder-title-group{
  display:flex;
  align-items:center;
  gap:9px;
  flex-wrap:wrap;
}
.software-reminder-badge{
  display:inline-flex;
  align-items:center;
  gap:4px;
  font-size:var(--font-size-label);
  font-weight:650;
  padding:2px 8px;
  border-radius:6px;
}
.software-reminder-badge.active{
  background:var(--c-7c3aed-bg);
  color:#ffffff;
  box-shadow:0 1px 3px rgba(124,58,237,.25);
}
.software-reminder-badge.empty{
  background:var(--c-ede9fe-bg);
  color:var(--c-6b21a8-text);
}
.software-reminder-counts{
  font-size:var(--font-size-body-sm);
  color:var(--c-581c87-text);
  font-weight:500;
}
.software-reminder-counts strong{
  font-weight:700;
  color:var(--c-6b21a8-text);
}
.software-reminder-tip{
  font-size:var(--font-size-caption);
  color:var(--c-7e22ce-text);
  background:var(--c-f3e8ff-bg);
  padding:2px 8px;
  border-radius:var(--radius-sm);
  font-weight:500;
}
.software-reminder-text{
  font-size:var(--font-size-body-sm);
  color:var(--muted-text);
}
.software-reminder-text strong{
  color:var(--ink-text);
}
.software-reminder-grid{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:12px;
}
.software-reminder-pane{
  border:1px solid var(--c-ede9fe-border);
  background:var(--surface-panel);
  border-radius:9px;
  padding:10px 12px;
  display:flex;
  flex-direction:column;
  gap:7px;
}
.software-reminder-pane.has-events{
  border-color:var(--c-d8b4fe-border);
  background:var(--surface-panel);
  box-shadow:0 1px 4px rgba(124,58,237,.06);
}
.pane-header{
  display:flex;
  align-items:center;
  justify-content:space-between;
  font-size:var(--font-size-label);
  font-weight:650;
  color:var(--c-4c1d95-text);
  padding-bottom:5px;
  border-bottom:1px dashed var(--c-f3e8ff-border);
}
.pane-count{
  font-size:var(--font-size-caption);
  font-weight:600;
  color:var(--c-7c3aed-text);
}
.pane-empty{
  font-size:var(--font-size-label);
  color:var(--muted-text);
  padding:6px 2px;
}
.software-reminder-items{
  display:flex;
  flex-direction:column;
  gap:6px;
}
.software-reminder-item{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:10px;
  padding:8px 10px;
  border:1px solid var(--c-e9d5ff-border);
  background:var(--c-fbf8ff-bg);
  border-radius:7px;
  cursor:pointer;
  text-align:left;
  transition:all .15s ease;
  width:100%;
}
.software-reminder-item:hover{
  background:var(--c-f3e8ff-bg);
  border-color:var(--c-a855f7-border);
  transform:translateY(-1px);
  box-shadow:0 2px 6px rgba(124,58,237,.12);
}
.item-room-slot{
  display:flex;
  flex-direction:column;
  gap:2px;
  min-width:75px;
  flex-shrink:0;
}
.item-room-pill{
  font-size:var(--font-size-caption);
  font-weight:700;
  color:var(--c-6b21a8-text);
  background:var(--c-ede9fe-bg);
  padding:1px 6px;
  border-radius:var(--radius-sm);
  display:inline-block;
  width:fit-content;
}
.item-time{
  font-size:var(--font-size-caption);
  font-variant-numeric:tabular-nums;
  font-weight:600;
  color:var(--c-4c1d95-text);
}
.item-main{
  display:flex;
  flex-direction:column;
  gap:2px;
  flex-grow:1;
  min-width:0;
}
.item-title{
  font-size:var(--font-size-body-sm);
  color:var(--c-1e1b4b-text);
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
.item-person{
  font-size:var(--font-size-caption);
  color:var(--c-6b21a8-text);
}
.item-btn-arrow{
  font-size:var(--font-size-caption);
  color:var(--c-7c3aed-text);
  font-weight:600;
  white-space:nowrap;
  padding-left:4px;
}

@media(max-width:768px){
  .software-reminder-grid{
    grid-template-columns:1fr;
  }
}

/* ========================================================
   Refactored Reference / Calendar Page Styles
   ======================================================== */

/* Sections in Reference */

/* Bell Schedule 3-Column Layout */

/* Room & Rules Grid */

/* Calendar Table Enhancement */
.ref-calendar-wrapper{
  overflow:auto;
  border:1px solid var(--line-border);
  border-radius:10px;
  background:var(--surface-panel);
}
.ref-badge{
  display:inline-block;
  padding:2px 8px;
  border-radius:5px;
  font-size:var(--font-size-caption);
  font-weight:600;
  background:var(--surface-muted);
  color:var(--c-334155-text);
}
.ref-badge.active{
  background:var(--c-2563eb-bg);
  color:#ffffff;
}
.ref-badge.holiday{
  background:var(--c-fee2e2-bg);
  color:var(--c-b91c1c-text);
}
.ref-badge.event{
  background:var(--c-fef3c7-bg);
  color:var(--c-b45309-text);
}
.ref-badge.vacation{
  background:var(--c-e0e7ff-bg);
  color:var(--c-4338ca-text);
}

/* Downloads & Resource Cards */

@media(max-width:900px),(max-height:480px) and (orientation:landscape){
}

/* ========================================================
   PWA & Add to Desktop / Home Screen Styles
   ======================================================== */
/* The install button lives in the header actions menu in every frame (css/layout.css gives menu items their skin), so only what is
   specific to it stays here: the weight and the icon colours. */
.install-btn{
  display:inline-flex;
  align-items:center;
  gap:6px;
  font-weight:600;
  transition:all .15s ease;
}
.install-btn svg{
  flex-shrink:0;
  stroke:var(--c-2563eb-text);
}
.install-btn.installed{
  cursor:default;
}
.install-btn.installed svg{
  stroke:var(--c-10b981-text);
}

.install-guide-box{
  display:flex;
  flex-direction:column;
  gap:14px;
}
.install-guide-app{
  display:flex;
  align-items:center;
  gap:14px;
  padding-bottom:12px;
  border-bottom:1px solid var(--line-border);
}
.install-guide-app-info{
  display:flex;
  flex-direction:column;
  gap:4px;
}
.install-guide-app-info strong{
  font-size:1.0625rem;
  color:var(--ink-text);
}
.install-pwa-badge{
  font-size:var(--font-size-caption);
  color:var(--c-2563eb-text);
  background:var(--surface-info-soft);
  border:1px solid var(--c-bfdbfe-border);
  padding:2px 8px;
  border-radius:var(--radius-pill);
  width:fit-content;
  font-weight:550;
}
.install-tabs{
  display:grid;
  grid-template-columns:repeat(4, minmax(0, 1fr));
  gap:6px;
}
.install-tab-btn{
  padding:7px 4px;
  font-size:0.78rem;
  font-weight:600;
  border:1px solid var(--line-border);
  background:var(--c-f8fafc-bg);
  color:var(--muted-text);
  border-radius:var(--radius-md);
  cursor:pointer;
  white-space:nowrap;
  text-align:center;
  transition:all .12s;
}
.install-tab-btn.active{
  background:var(--c-2563eb-bg);
  color:#ffffff;
  border-color:var(--c-2563eb-border);
  box-shadow:0 1px 3px rgba(37,99,235,.2);
}
.install-steps-list{
  list-style:none;
  margin:0;
  padding:0;
  display:flex;
  flex-direction:column;
  gap:10px;
}
.install-step-item{
  display:flex;
  align-items:flex-start;
  gap:10px;
  padding:10px 12px;
  background:var(--c-f8fafc-bg);
  border-radius:var(--radius-md);
  border:1px solid var(--c-e2e8f0-border);
  font-size:var(--font-size-body-sm);
  line-height:1.55;
  color:var(--ink-text);
}
.install-step-num{
  width:22px;
  height:22px;
  border-radius:50%;
  background:var(--c-2563eb-bg);
  color:#ffffff;
  font-size:var(--font-size-caption);
  font-weight:700;
  display:flex;
  align-items:center;
  justify-content:center;
  flex-shrink:0;
  margin-top:1px;
}
.install-alert{
  padding:10px 12px;
  border-radius:var(--radius-md);
  background:var(--c-fef3c7-bg);
  border:1px solid var(--c-fde68a-border);
  color:var(--c-92400e-text);
  font-size:var(--font-size-label);
  line-height:1.5;
  display:flex;
  align-items:flex-start;
  gap:8px;
  margin-bottom:10px;
}
@media(max-width:600px){
  .install-tabs{
    grid-template-columns:repeat(2, minmax(0, 1fr));
  }
}

.install-guide-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 14px;
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--line-border);
}

.install-guide-footer-tip {
  font-size: var(--font-size-label);
  color: var(--muted-text);
  line-height: 1.45;
  flex: 1;
}

.install-close-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 24px;
  height: 42px;
  font-size: 0.9375rem;
  font-weight: 600;
  border-radius: 9px;
  white-space: nowrap;
  background: linear-gradient(180deg, var(--c-2563eb-bg) 0%, var(--c-1d4ed8-bg) 100%);
  border: 1px solid var(--c-1d4ed8-border);
  color: #ffffff;
  box-shadow: 0 2px 6px rgba(37, 99, 235, 0.22);
  transition: all 0.15s ease;
  cursor: pointer;
  flex-shrink: 0;
}

.install-close-btn:hover {
  background: var(--c-1d4ed8-bg);
  box-shadow: 0 4px 12px rgba(37, 99, 235, 0.35);
  transform: translateY(-1px);
}

.install-close-btn:active {
  transform: translateY(0);
  box-shadow: 0 1px 3px rgba(37, 99, 235, 0.2);
}

@media(max-width:600px){
  .install-guide-footer {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    margin-top: 14px;
    padding-top: 12px;
  }
  .install-guide-footer-tip {
    text-align: center;
    font-size: var(--font-size-caption);
  }
  .install-close-btn {
    width: 100%;
    height: 44px;
    font-size: var(--font-size-body);
  }
}

/* ========================================================
   Relocation to Sanjiao (润杰迁三教) Styles
   ======================================================== */
.top-action-btn.relocation-btn{
  display:inline-flex;
  align-items:center;
  gap:6px;
  background:var(--c-f5f3ff-bg);
  border:1px solid var(--c-ddd6fe-border);
  color:var(--c-6d28d9-text);
  font-weight:600;
  transition:all .15s ease;
}
.top-action-btn.relocation-btn:hover{
  background:var(--c-ede9fe-bg);
  border-color:var(--c-c4b5fd-border);
  color:var(--c-5b21b6-text);
}
.top-action-btn.relocation-btn svg{
  flex-shrink:0;
  stroke:var(--c-7c3aed-text);
}

.inline-notice-btn{
  background:var(--surface-panel);
  border:1px solid var(--c-f59e0b-border);
  color:var(--c-b45309-text);
  font-weight:600;
  font-size:var(--font-size-caption);
  padding:2px 8px;
  border-radius:5px;
  cursor:pointer;
  margin-left:6px;
}
.inline-notice-btn:hover{
  background:var(--c-fef3c7-bg);
}

/* Detail modal relocation banner */
.relo-alert-box{
  background:linear-gradient(135deg, var(--c-f5f3ff-bg) 0%, var(--surface-info-soft) 100%);
  border:1px solid var(--c-c4b5fd-border);
  border-left:4px solid var(--c-7c3aed-border);
  border-radius:9px;
  padding:13px 15px;
  margin-bottom:16px;
  display:flex;
  flex-direction:column;
  gap:8px;
}
.relo-alert-head{
  display:flex;
  align-items:center;
  gap:9px;
  flex-wrap:wrap;
}
.relo-badge{
  font-size:var(--font-size-caption);
  font-weight:700;
  background:var(--c-7c3aed-bg);
  color:#ffffff;
  padding:2px 8px;
  border-radius:var(--radius-sm);
}
.relo-alert-title{
  font-size:0.9375rem;
  color:var(--c-1e1b4b-text);
}
.relo-room-dest{
  color:var(--c-6d28d9-text);
  font-weight:750;
  background:var(--c-ede9fe-bg);
  padding:1px 7px;
  border-radius:5px;
  border:1px solid var(--c-ddd6fe-border);
}
.relo-alert-desc{
  margin:0;
  font-size:var(--font-size-label);
  color:var(--c-4c1d95-text);
  line-height:1.55;
}
.relo-quick-btn{
  font-size:0.78125rem;
  font-weight:600;
  color:var(--c-4338ca-text);
  background:var(--surface-panel);
  border:1px solid var(--c-c7d2fe-border);
  border-radius:6px;
  padding:5px 11px;
  cursor:pointer;
  width:fit-content;
  transition:all .12s;
}
.relo-quick-btn:hover{
  background:var(--c-eef2ff-bg);
  border-color:var(--c-818cf8-border);
}

/* Relocation Dialog Modal */
dialog.relocation-modal{
  width:min(1100px, calc(100vw - 20px));
  max-width:calc(100vw - 20px);
}
.relo-modal-body{
  padding:18px 22px;
  display:flex;
  flex-direction:column;
  gap:16px;
}
.relo-info-card{
  background:var(--c-fcfaff-bg);
  border:1px solid var(--c-e9d5ff-border);
  border-radius:10px;
  padding:14px 16px;
  display:flex;
  flex-direction:column;
  gap:10px;
}
.relo-info-head{
  display:flex;
  align-items:center;
  gap:10px;
  flex-wrap:wrap;
}
.relo-info-head strong{
  font-size:0.9375rem;
  color:var(--c-2e1065-text);
}
.relo-info-badge{
  font-size:var(--font-size-caption);
  font-weight:700;
  color:var(--c-6b21a8-text);
  background:var(--c-f3e8ff-bg);
  border:1px solid var(--c-d8b4fe-border);
  padding:2px 8px;
  border-radius:var(--radius-pill);
}
.relo-info-desc{
  margin:0;
  font-size:var(--font-size-label);
  color:var(--c-4c1d95-text);
  line-height:1.6;
}
.relo-info-actions{
  display:flex;
  align-items:center;
  justify-content:space-between;
  flex-wrap:wrap;
  gap:10px;
  padding-top:6px;
  border-top:1px dashed var(--c-e9d5ff-border);
}
.relo-download-btn{
  display:inline-flex;
  align-items:center;
  gap:6px;
  font-size:var(--font-size-label);
  font-weight:600;
  color:var(--c-15803d-text);
  background:var(--c-f0fdf4-bg);
  border:1px solid var(--c-bbf7d0-border);
  padding:5px 12px;
  border-radius:6px;
  text-decoration:none;
  transition:all .12s;
}
.relo-download-btn:hover{
  background:var(--c-dcfce7-bg);
  border-color:var(--c-86efac-border);
}
.relo-count-indicator{
  font-size:var(--font-size-label);
  color:var(--muted-text);
  font-weight:550;
}

/* Toolbar & Filter Chips */
.relo-toolbar{
  display:flex;
  flex-direction:column;
  gap:10px;
}
.relo-search-wrapper{
  position:relative;
  display:flex;
  align-items:center;
}
.relo-search-wrapper svg{
  position:absolute;
  left:12px;
  stroke:var(--muted-text);
  pointer-events:none;
}
.relo-search-wrapper input{
  width:100%;
  height:40px;
  padding:6px 12px 6px 36px;
  font-size:var(--font-size-body-sm);
  border:1px solid var(--line-border);
  border-radius:var(--radius-md);
  background:var(--surface-panel);
}
.relo-search-wrapper input:focus{
  border-color:var(--c-7c3aed-border);
  outline:2px solid var(--c-ddd6fe-border);
}
.relo-filter-chips{
  display:flex;
  flex-wrap:wrap;
  gap:7px;
}
.relo-chip{
  font-size:0.78125rem;
  font-weight:600;
  padding:5px 11px;
  border-radius:6px;
  border:1px solid var(--line-border);
  background:var(--c-f8fafc-bg);
  color:var(--muted-text);
  cursor:pointer;
  transition:all .12s;
}
.relo-chip:hover{
  background:var(--surface-muted);
  color:var(--ink-text);
}
.relo-chip.active{
  background:var(--c-7c3aed-bg);
  color:#ffffff;
  border-color:var(--c-7c3aed-border);
  box-shadow:0 1px 3px rgba(124,58,237,.2);
}

/* Relocation Table */
.relo-table-wrap{
  max-height:50vh;
  overflow:auto;
  border:1px solid var(--line-border);
  border-radius:9px;
  background:var(--surface-panel);
}
.relo-table{
  width:100%;
  border-collapse:separate;
  border-spacing:0;
  font-size:var(--font-size-label);
}
.relo-table th{
  position:sticky;
  top:0;
  z-index:2;
  background:var(--surface-subtle);
  padding:10px 12px;
  font-weight:650;
  color:var(--ink-text);
  border-bottom:1px solid var(--line-border);
  white-space:nowrap;
}
.relo-table td{
  padding:9px 12px;
  border-bottom:1px solid var(--c-f0f3f8-border);
  vertical-align:middle;
}
.relo-table tr:hover td{
  background:var(--c-faf8ff-bg);
}
.relo-course-name{
  display:block;
  font-size:var(--font-size-body-sm);
  color:var(--ink-text);
}
.relo-course-code{
  display:block;
  font-size:0.71875rem;
  color:var(--muted-text);
}
.relo-orig-pill{
  display:inline-block;
  font-size:var(--font-size-caption);
  padding:2px 7px;
  border-radius:var(--radius-sm);
  background:var(--surface-muted);
  color:var(--c-475569-text);
  border:1px solid var(--c-e2e8f0-border);
  white-space:nowrap;
}
.relo-dest-pill{
  display:inline-block;
  font-size:var(--font-size-label);
  font-weight:700;
  padding:2px 8px;
  border-radius:5px;
  white-space:nowrap;
}
.relo-dest-pill.room-blue{
  background:var(--surface-info-soft);
  color:var(--c-1d4ed8-text);
  border:1px solid var(--c-bfdbfe-border);
}
.relo-dest-pill.room-purple{
  background:var(--c-f5f3ff-bg);
  color:var(--c-6d28d9-text);
  border:1px solid var(--c-ddd6fe-border);
}
.relo-week-pill{
  font-size:var(--font-size-caption);
  font-weight:600;
  color:var(--c-374151-text);
  background:var(--c-f3f4f6-bg);
  padding:2px 6px;
  border-radius:var(--radius-sm);
  white-space:nowrap;
}

/* Reference page relocation section */
.relo-mapping-card{
  background:var(--c-fbf9ff-bg);
  border:1px solid var(--c-ede9fe-border);
  border-radius:var(--radius-md);
  padding:12px 14px;
  display:flex;
  flex-direction:column;
  gap:6px;
}
.relo-mapping-head{
  display:flex;
  align-items:center;
  gap:8px;
  flex-wrap:wrap;
}
.relo-from-tag{
  font-size:var(--font-size-caption);
  padding:2px 7px;
  border-radius:var(--radius-sm);
  background:var(--c-e2e8f0-bg);
  color:var(--c-334155-text);
  font-weight:600;
}
.relo-arrow{
  font-size:var(--font-size-body-sm);
  color:var(--c-7c3aed-text);
  font-weight:700;
}
.relo-to-tag{
  font-size:var(--font-size-label);
  font-weight:700;
  padding:2px 8px;
  border-radius:5px;
  background:var(--c-7c3aed-bg);
  color:#ffffff;
}
.relo-mapping-desc{
  margin:0;
  font-size:var(--font-size-caption);
  color:var(--muted-text);
  line-height:1.45;
}

@media(max-width:768px){
}

/* Table headers name a room by its number only; the rest opens from a click (views/dialogs.js roomInfoDialog). */
table.schedule .roomhead { display: block; width: 100%; min-height: 32px; padding: 4px 6px; border: 0; border-radius: 6px; background: transparent; color: var(--ink-text); font-size: var(--font-size-body); font-weight: 650; line-height: 1.3; text-align: left; cursor: pointer; }
table.schedule .roomhead:hover { background: var(--blue-bg); color: var(--blue-text); }
.room-facts { display: grid; gap: 6px; margin: 0 0 12px; }
.room-facts > div { display: flex; gap: 12px; }
.room-facts dt { flex: none; width: 4.5em; color: var(--muted-text); }
.room-facts dd { margin: 0; }
.room-info-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }

/* ---- Table density and fill ----
   A row is as tall as its tallest card, so every other cell in it used to stop short and leave a blank strip.
   `height: 1px` on the cell lets children size themselves to the full row (the usual table-cell percentage trick),
   so free blocks and single cards now fill their cell. Cards are tighter so a day fits on one screen. */
table.schedule tbody td { height: 1px; }
table.schedule td > .empty-cell { height: 100%; min-height: 56px; }
table.schedule td > .event:only-child { height: 100%; margin-bottom: 0; }
table.schedule .event { padding: 7px 8px 6px; line-height: 1.35; }
table.schedule .event .event-title { font-size: var(--font-size-label); line-height: 1.35; }
table.schedule .event .event-time { margin-top: 3px; }
table.schedule .event .event-meta { margin-top: 1px; line-height: 1.35; }
table.schedule .week-summary { height: 100%; }

/* Centered room headers over their columns (the sticky corner and the row labels stay left). */
table.schedule thead .roomhead { text-align: center; }

/* ==== moved here from css/design-tokens.css (Phase 3a): component rules that were mixed into the tokens file.
   Same rules, same relative order as before (design-tokens.css was loaded right after this file). Their colours already
   come from theme.css tokens. They are migrated to component layers in Phase 3c–3e. ==== */
/* Touch targets on phones (WCAG 2.5.8 requires >= 24px; we aim for 36–44px). */
@media (max-width: 900px), (max-height: 480px) and (orientation: landscape) {
  .group-btn,.seg-btn,.install-tab-btn,.ref-asset-btn { min-height: var(--tap-min); }
  .inline-notice-btn, .duty-link { min-height: 36px; padding-block: 6px; }
  summary { min-height: var(--tap-min); display: flex; align-items: center; }
  label.small:has(> input[type="checkbox"]) { display: inline-flex; align-items: center; gap: 8px; min-height: var(--tap-min); }
  input[type="checkbox"] { width: 20px; height: 20px; }
}

/* Dense table cells keep at least the WCAG 2.5.8 minimum target size (24px). */
table.schedule .duty-link { min-height: 24px; padding-block: 4px; }

/* ---- Theme switch ---- */

.theme-btn { display: inline-flex; align-items: center; gap: 6px; }
.theme-btn .ti { display: none; }
:root[data-theme-pref="auto"] .theme-btn .ti-auto,
:root[data-theme-pref="light"] .theme-btn .ti-light,
:root[data-theme-pref="dark"] .theme-btn .ti-dark { display: inline-block; }
/* The theme button sits in the actions menu in every frame, so its label always shows. */
.theme-options { display: grid; gap: 10px; border: 0; margin: 0; padding: 0; }
.theme-option { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid var(--line-border); border-radius: var(--radius-lg); background: var(--paper-bg); cursor: pointer; min-height: var(--tap-min); }
.theme-option:has(input:checked) { border-color: var(--blue-border); background: var(--softblue-bg); }
.theme-option:has(input:focus-visible) { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.theme-option input { width: 18px; height: 18px; accent-color: var(--blue-bg); flex: none; }
.theme-option-icon { font-size: var(--font-size-title-sm); flex: none; }
.theme-option-text { display: grid; gap: 2px; }
.theme-option-text small { color: var(--muted-text); font-size: var(--font-size-label); }
.theme-status { margin: 14px 2px 0; color: var(--muted-text); font-size: var(--font-size-body-sm); }

/* Smooth the switch, but never for people who ask for less motion. */
@media (prefers-reduced-motion: no-preference) {
  body,.panel,.stat,.event,.tag,dialog { transition: background-color .25s ease, color .25s ease, border-color .25s ease; }
}

/* Dark mode: legend swatches reuse the week-grid block colours so the key matches the cells. */
:root[data-theme="dark"] .swatch { background: var(--c-79a0ed-bg); border-color: var(--c-79a0ed-bg); }
:root[data-theme="dark"] .swatch.makeup { background: var(--c-da8c9b-bg); border-color: var(--c-da8c9b-bg); }
:root[data-theme="dark"] .swatch.reservation { background: var(--c-d3ad67-bg); border-color: var(--c-d3ad67-bg); }
:root[data-theme="dark"] .swatch.software { background: var(--c-a855f7-bg); border-color: var(--c-a855f7-bg); }
:root[data-theme="dark"] .swatch.free { background: var(--c-dceddf-bg); border-color: var(--c-dceddf-bg); }
:root[data-theme="dark"] .swatch.unknown { background: var(--c-e1e5eb-bg); border-color: var(--c-e1e5eb-bg); }

/* Reference-page bell schedule rests and warning callouts (colours come from theme.css). */
.install-alert--warn { background: var(--c-fee2e2-bg); border-color: var(--c-fecaca-border); color: var(--c-991b1b-text); }

/* Small controls that were below the 24px minimum target size. */

input[type="checkbox"], input[type="radio"] { width: 18px; height: 18px; }

/* Dialogs paint the page's card colour instead of the browser default (near-black in dark mode). Light is unchanged: both are white. */
dialog { background: var(--paper-bg); }

/* Windows high-contrast mode keeps state markers visible. */
@media (forced-colors: active) {
  .event,.tag{ border: 1px solid CanvasText; }
}


/* ===================== moved from css/compact.css (Phase 3e.4.3.1) ===================== */
/* Compact application bar. Loaded last: it only changes layouts at <= 900px; the desktop header is untouched.
   Layout budget at 390x844: controls row 52 + day strip 52 = about 108px before the schedule (there is no title bar:
   the bottom navigation says where you are, the summary lives in the panel, and the bell / menu sit in the controls row). */

/* The wrapper is invisible on desktop, so the original header layout is unchanged. */



@media (max-width: 900px), (max-height: 480px) and (orientation: landscape) {
  /* The sidebar brand block moves into the bar; the bottom navigation (fixed) stays where it is. */




  .stats, #notices { display: none; }          /* summary line + bell replace them */






  /* Row 1 is the controls row: the old title bar is flattened away. The title stays for screen readers. */









  .badge { display: inline-grid; place-items: center; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px; background: var(--badge-bg); color: var(--badge-fg); font-size: 0.6875rem; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
  .badge[hidden] { display: none; }
  .badge--alert { background: var(--badge-alert-bg); color: var(--badge-alert-fg); }


  /* The old action row becomes the "more" menu. */







  /* Week stepper, "today" (only when you are not already on today) and filters. */









  /* Row 2: day strip. */



  /* "· 今天" would wrap in the narrow buttons: show a dot under the date instead (aria-current=date keeps it accessible). */



  /* Anchors must clear the sticky bar. */
}

/* Narrow phones (320px): squeeze the controls row instead of wrapping it, which would cost another 48px. */
@media (max-width: 340px) {




   /* chevron */


}

/* Short landscape screens (phones turned sideways, height < 480px): height is the scarce axis.
   Navigation moves from the bottom to a slim rail on the left, and the three header rows collapse into one,
   so the schedule starts about 55px from the top instead of 160px. */
@media (max-height: 480px) and (orientation: landscape) {
  :root { --rail-w: calc(56px + env(safe-area-inset-left)); --pad-l: calc(var(--rail-w) + 8px); --pad-r: calc(10px + env(safe-area-inset-right)); }








  /* One row: week stepper, today, filters, day strip, bell and menu. The title is still there for screen readers. */














}
/* ~667px landscape: squeeze the controls so the day strip still fits on the same row (otherwise the bar wraps to two). */




/* ---- Wide screens: the schedule comes first. Everything that is not "the table" (legend, hints, reminders,
   notices, summary cards) sits below it, and the header and panel head are slimmed so the grid starts high. ---- */
@media (min-width: 901px) and (min-height: 481px) {



              /* the sidebar already says which term this is */




  .schedule-panel > .panel-head, .matrix-panel > .panel-head { padding: 10px 16px; }
  .schedule-panel > .panel-head > div:first-child, .matrix-panel > .panel-head > div:first-child { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 12px; }
  .schedule-panel > .panel-head h2, .matrix-panel > .panel-head h2 { margin: 0; font-size: var(--font-size-body-lg); }
  .schedule-panel > .panel-head p, .matrix-panel > .panel-head p { margin: 0; }
  .schedule-panel > .panel-head .panel-actions button, .matrix-panel > .panel-head .panel-actions button { min-height: 36px; }
  .schedule-panel .schedule-tools, .matrix-panel .schedule-tools { padding: 6px 16px; }
  .schedule-panel .schedule-tools button, .schedule-panel .schedule-tools select { min-height: 36px; }

  /* Reference material under the grid. */
  .schedule-panel > .legend, .matrix-panel > .legend { border-top: 1px solid var(--line-border); }
  #view + #notices { margin-top: 14px; }
  #notices:empty { display: none; }
}

/* ---- Table navigation (wide screens, classic table only; see ui/table-nav.js) ---- */
@media (min-width: 901px) and (min-height: 481px) {
  /* overflow:hidden would make the panel the scroll container and stop the docked bar from sticking to the window. */
  @supports (overflow: clip) { .schedule-panel { overflow: clip; } }

  /* One bar: scrollbar and minimap in one. Cells are the columns (lit = something scheduled); the window is what is on screen. */
}

/* ---- The table box must never trap the page scroll: at its end, wheel and touch carry on to the page (every size). ---- */
.schedule-panel .schedule-desktop { overscroll-behavior-y: auto; overscroll-behavior-x: contain; }

/* ---- Wide screens: the table box fills the space left in the window ---- */
@media (min-width: 901px) and (min-height: 481px) {
  .schedule-panel .schedule-desktop { max-height: var(--table-fit, 72dvh); }
}


/* ===================== moved from css/legacy-overrides.css (Phase 3e.4.3.1) ===================== */
/* Unlayered leftovers of the Phase 3c migration — this sheet must stay OUT of every @layer, and stay last in index.html.
   Two kinds of rules live here, and only these:
     1. The detail dialog's phone bottom-sheet chrome. It belongs to the Phase 3d "detail host" and is kept byte-for-byte
        as it was in css/matrix.css until then. It has to out-rank `.dialog-head` / `dialog .dialog-body` in styles.css
        and ui-hardening.css, exactly as it did when the matrix sheet was unlayered.
     2. The one matrix rule that legitimately overrides another *legacy* sheet: the empty software reminder bar is
        ui-hardening.css's to style, and only the matrix panel hides it on compact screens.
   Everything else that used to be in css/matrix.css now lives in that file's `@layer components` block.
   See docs/CSS-ARCHITECTURE.md §11. */

/* ---- Bottom sheet: the shared detail dialog slides up from the bottom edge on phones. ---- */
@media (max-width: 600px) {
  dialog#detailDialog {
    width: 100%; max-width: 100%; max-height: 88dvh;
    margin: auto 0 0; border-radius: 18px 18px 0 0; border-bottom: 0;
    padding-bottom: env(safe-area-inset-bottom);
  }
  dialog#detailDialog.wide { max-height: 94dvh; }
  dialog#detailDialog .dialog-head::before { content: ''; position: absolute; top: 6px; left: 50%; width: 36px; height: 4px; margin-left: -18px; border-radius: var(--radius-xs); background: var(--line-border); }
  dialog#detailDialog .dialog-head { padding-top: 18px; }
  dialog#detailDialog .dialog-body { max-height: calc(88dvh - 74px); }
}
@media (max-width: 600px) and (prefers-reduced-motion: no-preference) {
  dialog#detailDialog[open] { animation: sheet-up 0.2s ease-out; }
  @keyframes sheet-up { from { transform: translateY(32px); opacity: 0; } to { transform: none; opacity: 1; } }
}

.cell-list { display: grid; gap: 8px; }
.cell-list .event { margin: 0; }

/* The matrix panel drops the empty "no software installs in the next two days" strip on phones and short landscape. */
@media (max-width: 900px), (max-height: 480px) and (orientation: landscape) {
  .matrix-panel .software-reminder-bar.empty { display: none; }
}
}

/* ---- the one rule that has to out-rank css/matrix.css ------------------------------------------------
   At <=520px the compact chrome gives every panel head (and the legend) 12px of side padding. css/matrix.css
   hides its own quiet head with `.matrix-panel > .panel-head.m-head-quiet { padding: 0; … }` (specificity 0,3,0);
   while these sheets were unlayered that generic 0,1,0 rule still won, because an unlayered rule beats every
   layer no matter how specific it is. Now that everything is layered, the only levers left are specificity and
   !important, and both are off-limits for this migration — so the rule keeps its exact declaration and moves to
   the LAST screen layer, which reproduces "it wins" without touching either. Its computed effect is unchanged
   (and it is the only rule in these sheets that needs this). */
@layer views {
  @media (max-width: 520px) {
    .panel-head, .legend { padding-left: 12px; padding-right: 12px; }
  }
}
