﻿/* ============================================================================
   theme.css — Global design-token & polish layer (Radzen "Standard" overrides)
   ----------------------------------------------------------------------------
   Loaded AFTER app.css / standard-base.css. Token overrides use !important so
   they win over Radzen's injected values (same proven pattern app.css uses for
   fonts). This is an additive FOUNDATION — shape, elevation, motion, typography
   hierarchy, and interaction/focus states. It intentionally does NOT change the
   brand blue primary (#1151f3); a palette refresh can follow once reviewed.

   Rollback: remove the <link href="css/theme.css"> in Components/App.razor.
   ============================================================================ */

/* — Shape: softer containers, consistent inner radius ———————————————————— */
:root,
html {
    --rz-border-radius: 6px !important;        /* inputs, buttons, chips, menus */
    --rz-card-border-radius: 10px !important;  /* cards, panels, dialogs        */

    /* — Border: Radzen 11 ใช้ --rz-border-color แต่ไม่เคยประกาศค่าไว้ในธีมไหนเลย
         คอมโพเนนต์ของเราจึงตกไปใช้ค่าสำรองที่ฮาร์ดโค้ดเป็นสีอ่อน (#e5e8ee/#d3d8e2)
         ซึ่งกลายเป็นเส้นขาวโพลนบนธีมมืด ประกาศไว้ที่เดียวโดยผสมจากสีตัวอักษร
         เพื่อให้ทุกจุดที่เรียก var(--rz-border-color) ปรับตามธีมเอง
         (ห้ามผูกกับ --rz-base-*: ธีมมืดของ Radzen ให้ค่าเหล่านั้นสว่างกว่าธีมสว่าง) */
    --rz-border-color: color-mix(in srgb, var(--rz-text-color) 18%, transparent) !important;

    /* — RadzenProfileMenu วาดเส้นคั่นซ้ายของตัวเองอยู่แล้ว (ul.rz-profile-menu มี
         border-inline-start) ซึ่งซ้ำกับเส้นคั่นที่ TopNavBar วาดไว้เอง กลายเป็นเส้นตั้งสองเส้น
         คนละสีห่างกัน ~11px ปิดของ Radzen ไว้ เก็บของเราที่เว้นบน-ล่าง 6px สวยกว่า
         (ต้องปิดที่ token ไม่ใช่ที่ selector เพราะธีมมืดสลับไปใช้ --rz-border-base-900 แล้วซ้ำเหมือนกัน) */
    --rz-profile-menu-border: none !important;

    /* — Elevation: softer shadows, subtly cool-tinted to match the gray base — */
    --rz-shadow-1: 0 1px 2px rgba(30, 41, 59, 0.06), 0 1px 1px rgba(30, 41, 59, 0.04) !important;
    --rz-shadow-2: 0 1px 3px rgba(30, 41, 59, 0.08), 0 4px 12px rgba(30, 41, 59, 0.05) !important;
    --rz-shadow-3: 0 2px 6px rgba(30, 41, 59, 0.08), 0 8px 20px rgba(30, 41, 59, 0.08) !important;
    --rz-shadow-4: 0 4px 10px rgba(30, 41, 59, 0.09), 0 12px 28px rgba(30, 41, 59, 0.10) !important;
    --rz-shadow-5: 0 6px 14px rgba(30, 41, 59, 0.10), 0 18px 36px rgba(30, 41, 59, 0.12) !important;
    --rz-shadow-6: 0 8px 18px rgba(30, 41, 59, 0.11), 0 24px 48px rgba(30, 41, 59, 0.14) !important;
}

/* — Motion: smooth, GPU-friendly transitions on interactive surfaces ————— */
html {
    scroll-behavior: smooth;
}

.rz-button,
.rz-card,
.rz-listbox-item,
.rz-tabview-title,
.rz-navigation-item-link,
a {
    transition: background-color .2s ease, color .2s ease, border-color .2s ease,
                box-shadow .2s ease, transform .12s ease !important;
}

/* Physical press feedback on buttons */
.rz-button:not(.rz-state-disabled):not(:disabled):active {
    transform: translateY(1px);
}

/* — Accessibility: one visible keyboard focus ring (hidden for mouse users) — */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
[tabindex]:focus-visible,
.rz-button:focus-visible,
.rz-textbox:focus-visible,
.rz-dropdown:focus-visible,
.rz-tabview-title:focus-visible {
    outline: 2px solid var(--rz-primary) !important;
    outline-offset: 2px !important;
}

:focus:not(:focus-visible) {
    outline: none;
}

/* — Dialogs: never taller than the screen ————————————————————————————————
   Radzen ตั้ง .rz-dialog { max-height: 100% } มาให้ ซึ่งพอดีขอบจอเป๊ะ ๆ ไม่เหลือที่หายใจ
   กฎนี้ลดเพดานลงเป็นสัดส่วนของ viewport ให้ทุก dialog เป็นค่าเริ่มต้น แล้วปล่อยให้
   .rz-dialog-content (flex: 0 1 auto; overflow: auto ของ Radzen) เลื่อนเนื้อหาข้างในเอง
   จงใจไม่ใส่ !important เพื่อให้ call site ที่ส่ง Style="max-height: ..." มาเองยังกำหนดได้อยู่
   — แต่ค่าที่ส่งมาต้องอิง viewport (dvh) หรือครอบด้วย min() เสมอ ห้ามเป็น px ล้วน
   เพราะ inline style ชนะกฎนี้ และ px ล้วนจะล้นจอบนเครื่องที่จอเตี้ยกว่าค่านั้น
   ต้องอยู่ในไฟล์นี้เท่านั้น: app.css ถูกโหลดก่อน standard-base.css จึงแพ้กฎของ Radzen */
.rz-dialog {
    max-height: 92dvh;
}

/* — Surfaces: refined card elevation + consistent radius —————————————————— */
.rz-card {
    box-shadow: var(--rz-shadow-2) !important;
    border-radius: var(--rz-card-border-radius) !important;
}

/* Cards used as clickable buttons get a subtle hover lift */
.CourseCardButton {
    transition: background-color .2s ease, box-shadow .2s ease, transform .12s ease !important;
    border-radius: 12px !important;
}

.CourseCardButton:hover {
    box-shadow: var(--rz-shadow-3) !important;
    transform: translateY(-2px);
}

/* — Course evaluation cards: entrance fade + hover micro-interactions ————— */
/* Entrance animates opacity only, so hover transforms stay free to run.     */
.course-card {
    animation: course-card-in .25s ease both;
    transition: border-color .18s ease, box-shadow .18s ease;
}

.CourseCardButton:hover .course-card {
    border-color: var(--rz-primary-light, #7db4e0);
}

.course-chevron {
    transition: transform .18s ease, background-color .18s ease;
}

.CourseCardButton:hover .course-chevron {
    transform: translateX(3px);
}

@keyframes course-card-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* Sections never opened for evaluation: whole card dimmed. Needs its own
   keyframes — course-card-in's fill pins animated opacity at 1, overriding
   any inline/class opacity. */
.course-card--closed {
    animation-name: course-card-in-dim;
}

@keyframes course-card-in-dim {
    from { opacity: 0; }
    to { opacity: .6; }
}

@media (prefers-reduced-motion: reduce) {
    .course-card { animation: none; transition: none; }
    .course-card--closed { opacity: .6; }
    .course-chevron { transition: none; }
    .CourseCardButton, .CourseCardButton:hover { transform: none; transition: none !important; }
}

/* — Inputs: soft brand-blue focus ring for clearer affordance ———————————— */
.rz-textbox:focus,
.rz-textarea:focus,
.rz-dropdown.rz-state-focused,
.rz-lookup.rz-state-focused {
    box-shadow: 0 0 0 3px var(--rz-primary-lighter) !important;
}

/* — Typography: tighter display hierarchy + tabular figures for data ————— */
.rz-text-display-h1, .rz-text-h1 { letter-spacing: -0.021em; line-height: 1.15; }
.rz-text-display-h2, .rz-text-h2 { letter-spacing: -0.018em; line-height: 1.18; }
.rz-text-display-h3, .rz-text-h3 { letter-spacing: -0.014em; line-height: 1.22; }
.rz-text-display-h4, .rz-text-h4 { letter-spacing: -0.010em; line-height: 1.28; }

.rz-text-h1, .rz-text-h2, .rz-text-h3,
.rz-text-display-h1, .rz-text-display-h2, .rz-text-display-h3 {
    font-weight: 600;
}

/* หัวเรื่องหลักของหน้า — ใช้คลาสเดียวทุกหน้า (แทนการใส่ font-weight ใน Style ราย
   หน้า ซึ่งเคยหลุดเป็น 400 บ้าง ค่า default ของ Radzen บ้าง) คู่กับ TextStyle.DisplayH4
   ไม่กำหนด margin ไว้ตรงนี้ เพราะแต่ละหน้าวางหัวเรื่องใน RadzenStack ที่มี Gap ต่างกัน */
.rz-text.page-title,
.page-title {
    font-weight: 700;
    text-wrap: balance;
}

/* Align numbers in data-dense surfaces (grids, tables, stat cards) */
.rz-data-grid, .rz-datatable, .rz-grid-table, .rz-datatable-data,
.rz-pager, tbody td {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

/* — Thin, unobtrusive scrollbars (modern polish) ————————————————————————— */
* {
    scrollbar-width: thin;
    scrollbar-color: color-mix(in srgb, var(--rz-text-color) 28%, transparent) transparent;
}

*::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

*::-webkit-scrollbar-thumb {
    background: color-mix(in srgb, var(--rz-text-color) 28%, transparent);
    border-radius: 8px;
    border: 2px solid transparent;
    background-clip: content-box;
}

*::-webkit-scrollbar-thumb:hover {
    background: color-mix(in srgb, var(--rz-text-color) 40%, transparent);
    background-clip: content-box;
}

/* — Setting-section status tints (semantic, separate from brand accent) — */
:root {
    --set-inherit: #6b52d6; --set-inherit-weak: #efeafc;
}
/* ต้องเกาะ data-theme ไม่ใช่ prefers-color-scheme: ธีมมาจากคุกกี้ EESTheme
   เครื่องที่ระบบเป็นสว่างแต่ผู้ใช้กดธีมมืดจะได้สีอ่อนค้างไว้ถ้าใช้ media query
   ค่าแอตทริบิวต์ตั้งจาก App.razor ตอนเรนเดอร์ และ syncThemeAttribute ใน interop.js ตามให้ตอนกดสลับ */
:root[data-theme="dark"] {
    --set-inherit: #a894f5; --set-inherit-weak: #211c38;
}

/* — Thai head-marks in data-grid headers ————————————————————————————— */
/* Radzen ตั้ง --rz-grid-header-line-height: 1rem บน font-size 0.875rem ซึ่งพอดีเป๊ะ
   สำหรับอักษรละติน แต่หัวคอลัมน์ .rz-column-title มี overflow:hidden สระบน/วรรณยุกต์ไทย
   (รหัสนักศึกษา, วันที่ส่ง, สถานะ) จึงโดนเฉือนหาย แก้ที่ token ตัวเดียวครอบทุกกริดทั้งระบบ
   รวมถึง .rz-density-compact ที่ไม่ได้ตั้ง token ตัวนี้ทับ — padding ของหัวตารางไม่ถูกแตะ
   ความสูงจึงเพิ่มแค่ตามบรรทัด และ .mgmt-grid ที่ตั้ง 1.35 เองไว้แล้วก็ยังชนะตามเดิม
   ไม่แตะ white-space/overflow ของหัวคอลัมน์: ธีมใช้ nowrap + ellipsis กันหัวยาวล้นทับ
   คอลัมน์แคบ (บางกริดกว้าง 80px) การปล่อยล้นเป็นคนละปัญหากับสระโดนเฉือน */
:root {
    --rz-grid-header-line-height: 1.5rem !important;
}

/* — Status pills: theme-aware tints ————————————————————————————————————
   ป้ายสถานะบนการ์ดเคยฮาร์ดโค้ดสีพื้นอ่อน/ตัวอักษรเข้มไว้ในคอมโพเนนต์ ธีมมืดจึงได้ก้อนสีขาว
   จ้าลอยอยู่บนพื้นดำ ย้ายมาเป็น token คู่สว่าง/มืด: ธีมมืดใช้พื้นเข้มอมสีของตัวเอง
   + ตัวอักษรสีอ่อนของสีเดียวกัน คุมคอนทราสต์ให้อ่านได้โดยไม่แย่งสายตาจากเนื้อหา
   ต้องเกาะ data-theme ไม่ใช่ prefers-color-scheme — ธีมมาจากคุกกี้ EESTheme (ดู --set-inherit) */
:root {
    --pill-gray-bg: #EDF0F4;  --pill-gray-fg: #4B5565;  --pill-gray-border: #DCE1E8;
    --pill-green-bg: #D7F0E2; --pill-green-fg: #00602F;
    --pill-blue-bg: #E3F1FA;  --pill-blue-fg: #14456B;
    --pill-amber-bg: #FDE9C8; --pill-amber-fg: #7A4D0B;
    --pill-red-bg: #FBE3E0;   --pill-red-fg: #8A2A20;
}

:root[data-theme="dark"] {
    --pill-gray-bg: #222831;  --pill-gray-fg: #B3BDCB;  --pill-gray-border: #363F4C;
    --pill-green-bg: #12301F; --pill-green-fg: #6FDCA4;
    --pill-blue-bg: #132938;  --pill-blue-fg: #7EC2F2;
    --pill-amber-bg: #302512; --pill-amber-fg: #F2C070;
    --pill-red-bg: #351A1B;   --pill-red-fg: #F2948C;
}

/* — Soft surface: กล่องเกร็ดข้อความ/รางจาง ๆ บนการ์ด ——————————————————
   ห้ามใช้ --rz-base-100 เพื่อการนี้: สเกล base ของ Radzen ตรึงความสว่างไว้
   (base-100 เป็นเทาอ่อนแม้ในธีมมืด) กล่องจึงสว่างโพลนบนการ์ดมืด — ใช้ token คู่นี้แทน */
:root {
    --surface-soft: #F4F6F9;
}

:root[data-theme="dark"] {
    --surface-soft: rgba(255, 255, 255, 0.06);
}
