@import url('https://fonts.googleapis.com/css2?family=Figtree:wght@400;500;600;700;800&family=IBM+Plex+Sans+Thai:wght@400;500;600;700&family=Sarabun:wght@400;500;600;700&family=Source+Sans+3:wght@400;500;600;700&display=swap');
:root {
color-scheme: light dark;
--design-unit: 4;
--transition: .22s cubic-bezier(.4, 0, .2, 1);
--app-focus-ring: var(--app-accent);
}
html {
scroll-behavior: smooth;
}
:root[data-theme="dark"] {
color-scheme: dark;
}
:root[data-theme="light"] {
color-scheme: light;
}
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
*, *::before, *::after {
scroll-behavior: auto !important;
animation-duration: .01ms !important;
animation-iteration-count: 1 !important;
transition-duration: .01ms !important;
}
}
/* Theme Selector and Culture Selector*/
.theme-selector,
.culture-selector {
display: inline-flex;
padding: .16rem;
border: 1px solid var(--app-border);
border-radius: .58rem;
background: var(--app-surface-muted);
}
.theme-selector button,
.culture-selector button {
border-radius: .4rem;
border: 0;
color: var(--app-foreground-muted);
background: transparent;
min-width: 1.85rem;
/* Matches the 2.35rem header CTA once the selector's padding and border are included. */
height: 1.91rem;
width: auto;
padding: .2rem .38rem;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: .66rem;
font-weight: 780;
cursor: pointer;
transition: color var(--transition), background-color var(--transition), box-shadow var(--transition);
}
.theme-selector button.active,
.culture-selector button.active {
color: var(--app-accent);
background: var(--app-surface);
box-shadow: 0 .15rem .45rem var(--app-shadow-color);
}
.theme-selector button:hover:not(.active),
.culture-selector button:hover:not(.active) {
color: var(--app-foreground);
background: var(--app-surface-hover);
}
.theme-selector button.active:hover,
.culture-selector button.active:hover {
background: var(--app-surface);
}
.theme-selector button:focus-visible,
.culture-selector button:focus-visible {
outline: 2px solid var(--app-accent);
outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
.theme-selector button,
.culture-selector button {
transition: none;
}
}
.app-form-control {
display: grid;
min-width: 0;
gap: .42rem;
color: var(--app-foreground);
}
.app-form-control__label {
width: fit-content;
font-size: .77rem;
font-weight: 760;
letter-spacing: .01em;
}
.app-form-control__input-wrap {
position: relative;
display: flex;
height: 2.8rem;
align-items: center;
border: 1px solid transparent;
border-radius: .7rem;
background: color-mix(in srgb, var(--app-surface-muted) 88%, var(--app-surface));
box-shadow: none;
transition: border-color .16s ease, box-shadow .16s ease, background-color .16s ease;
}
.app-form-control__input-wrap:hover {
border-color: transparent;
background: var(--app-surface-hover);
box-shadow: 0 .3rem .9rem var(--app-shadow-color);
}
.app-form-control__input-wrap:focus-within {
border-color: transparent;
background: var(--app-surface);
box-shadow: 0 0 0 .22rem var(--app-brand-soft), 0 .55rem 1.25rem var(--app-shadow-color);
}
.app-form-control.has-error .app-form-control__input-wrap { border-color: transparent; background: color-mix(in srgb, var(--app-danger-soft) 58%, var(--app-surface-muted)); box-shadow: inset .2rem 0 0 var(--app-danger); }
.app-form-control.has-error .app-form-control__input-wrap:focus-within { box-shadow: inset .2rem 0 0 var(--app-danger), 0 0 0 .22rem var(--app-danger-soft), 0 .55rem 1.25rem var(--app-shadow-color); }
.app-form-control:has(.modified.valid) .app-form-control__input-wrap { border-color: transparent; background: color-mix(in srgb, var(--app-success-soft) 46%, var(--app-surface-muted)); }
.app-form-control__icon {
position: absolute;
left: .82rem;
width: 1.15rem;
height: 1.15rem;
fill: none;
stroke: var(--app-accent);
stroke-width: 1.7;
stroke-linecap: round;
stroke-linejoin: round;
pointer-events: none;
}
.app-form-control__icon-content {
position: absolute;
left: .82rem;
display: grid;
width: 1.15rem;
height: 1.15rem;
place-items: center;
color: var(--app-accent);
pointer-events: none;
}
.app-form-control__icon-content svg {
width: 100%;
height: 100%;
fill: none;
stroke: currentColor;
stroke-width: 1.7;
stroke-linecap: round;
stroke-linejoin: round;
}
.app-form-control__input {
width: 100%;
min-width: 0;
height: 100%;
min-height: 0;
box-sizing: border-box;
padding: .66rem .78rem;
border: 0;
outline: 0;
background: transparent;
color: var(--app-foreground);
color-scheme: inherit;
font: inherit;
font-size: .9rem;
font-weight: 580;
}
.app-form-control__input:focus-visible { outline: 0; }
.app-form-control__input-wrap--has-icon .app-form-control__input { padding-inline-start: 2.9rem; }
.app-form-control textarea.app-form-control__input { height: auto; min-height: 7rem; padding: .75rem .8rem; resize: vertical; line-height: 1.55; }
.app-form-control__input-wrap--textarea { height: auto; min-height: 7rem; align-items: stretch; }
.app-form-control__input-wrap--select select { padding-inline: .8rem 2.5rem; appearance: none; cursor: pointer; }
.app-form-control__input-wrap--select.app-form-control__input-wrap--has-icon select { padding-inline-start: 2.9rem; }
.app-form-control__select-chevron { position: absolute; right: .8rem; width: 1rem; height: 1rem; fill: none; stroke: var(--app-accent); stroke-width: 1.7; pointer-events: none; }
.app-form-control__meta { display: flex; min-width: 0; align-items: start; justify-content: space-between; gap: .75rem; }
.app-form-control__meta > :first-child { min-width: 0; }
.app-form-control__counter { margin-inline-start: auto; color: var(--app-foreground-muted); font-size: .67rem; white-space: nowrap; }
.app-form-control__input::-webkit-calendar-picker-indicator {
width: 1.2rem;
height: 1.2rem;
padding: .35rem;
border-radius: .4rem;
cursor: pointer;
opacity: .72;
}
.app-form-control__input::-webkit-calendar-picker-indicator:hover {
background: var(--app-accent-soft);
opacity: 1;
}
.app-form-control__calendar-trigger,
.app-form-control__picker-trigger {
display: none;
width: 2.15rem;
height: 2.15rem;
margin-inline-end: .3rem;
padding: .48rem;
place-items: center;
flex: 0 0 auto;
border: 0;
border-radius: .5rem;
background: transparent;
color: var(--app-accent);
cursor: pointer;
}
.app-form-control__calendar-trigger:hover,
.app-form-control__picker-trigger:hover { background: var(--app-accent-soft); }
.app-form-control__calendar-trigger:focus-visible,
.app-form-control__picker-trigger:focus-visible { outline: 2px solid var(--app-focus-ring); outline-offset: 2px; }
.app-form-control__calendar-trigger:disabled,
.app-form-control__picker-trigger:disabled { cursor: not-allowed; opacity: .45; }
.app-form-control__calendar-trigger svg,
.app-form-control__picker-trigger svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
[data-app-calendar="popup"].is-popup-ready .app-form-control__calendar-trigger { display: grid; }
[data-app-calendar="popup"].is-popup-ready .app-form-control__input::-webkit-calendar-picker-indicator { display: none; }
[data-app-time="popup"].is-popup-ready .app-form-control__picker-trigger,
[data-app-datetime="popup"].is-popup-ready .app-form-control__picker-trigger { display: grid; }
[data-app-time="popup"].is-popup-ready .app-form-control__input::-webkit-calendar-picker-indicator,
[data-app-datetime="popup"].is-popup-ready .app-form-control__input::-webkit-calendar-picker-indicator { display: none; }
.app-calendar-popup {
position: fixed;
z-index: 20000;
width: min(20rem, calc(100vw - 1rem));
box-sizing: border-box;
padding: .75rem;
border: 1px solid var(--app-border);
border-radius: .3rem 1rem .3rem 1rem;
background: var(--app-surface);
color: var(--app-foreground);
box-shadow: 0 1.5rem 4rem var(--app-shadow-color);
overflow: auto;
max-height: calc(100dvh - 1rem);
}
.app-calendar-popup[hidden] { display: none; }
.app-calendar-popup__header { display: grid; grid-template-columns: 2.1rem minmax(0, 1fr) 2.1rem; align-items: center; gap: .4rem; margin-bottom: .55rem; }
.app-calendar-popup__period { display: grid; min-width: 0; grid-template-columns: minmax(0, 1fr) 5.3rem; gap: .3rem; }
.app-calendar-popup__period-select { width: 100%; min-width: 0; height: 2.1rem; box-sizing: border-box; padding: 0 1.55rem 0 .58rem; border: 1px solid transparent; border-radius: .55rem; outline: 0; background: var(--app-surface-muted); color: var(--app-foreground); font: inherit; font-size: .76rem; font-weight: 760; cursor: pointer; }
.app-calendar-popup__period-select:hover { border-color: var(--app-accent-border); background: var(--app-surface-hover); }
.app-calendar-popup__period-select:focus-visible { border-color: var(--app-brand); box-shadow: 0 0 0 2px var(--app-brand-soft); }
.app-calendar-popup__announcement { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.app-calendar-popup__nav { display: grid; width: 2.1rem; height: 2.1rem; padding: 0; place-items: center; border: 0; border-radius: .5rem; background: transparent; color: var(--app-foreground); font: inherit; font-size: 1.15rem; cursor: pointer; }
.app-calendar-popup__nav:hover { background: var(--app-surface-hover); }
.app-calendar-popup__weekdays, .app-calendar-popup__days { display: grid; grid-template-columns: repeat(7, 1fr); gap: .2rem; }
.app-calendar-popup__weekdays span { padding-block: .35rem; color: var(--app-foreground-muted); font-size: .58rem; font-weight: 800; text-align: center; text-transform: uppercase; }
.app-calendar-popup__day { display: grid; aspect-ratio: 1; padding: 0; place-items: center; border: 0; border-radius: .55rem; background: transparent; color: var(--app-foreground); font: inherit; font-size: .72rem; font-weight: 650; cursor: pointer; }
.app-calendar-popup__day:hover { background: var(--app-surface-hover); }
.app-calendar-popup__day.is-outside { color: var(--app-foreground-muted); opacity: .55; }
.app-calendar-popup__day.is-today { box-shadow: inset 0 0 0 1px var(--app-accent-border); color: var(--app-accent); }
.app-calendar-popup__day.is-selected { background: var(--app-brand); color: var(--app-on-brand); box-shadow: 0 .3rem .8rem var(--app-shadow-color); }
.app-calendar-popup__day:disabled { opacity: .28; cursor: not-allowed; }
.app-calendar-popup button:focus-visible { outline: 2px solid var(--app-focus-ring); outline-offset: 2px; }
.app-picker-popup {
position: fixed;
z-index: 20000;
width: min(18.75rem, calc(100vw - 1rem));
box-sizing: border-box;
padding: .8rem;
border: 1px solid var(--app-border);
border-radius: .3rem 1rem .3rem 1rem;
background: var(--app-surface);
color: var(--app-foreground);
box-shadow: 0 1.5rem 4rem var(--app-shadow-color);
}
.app-picker-popup__heading { display: flex; align-items: center; gap: .65rem; padding: .2rem .2rem .8rem; border-bottom: 1px solid var(--app-grid-line); }
.app-picker-popup__heading-icon { display: grid; width: 2rem; height: 2rem; place-items: center; border-radius: .65rem; background: var(--app-accent-soft); color: var(--app-accent); font-size: 1.2rem; }
.app-picker-popup__heading div { display: grid; gap: .05rem; }
.app-picker-popup__heading strong { font-size: .82rem; }
.app-picker-popup__heading small { color: var(--app-foreground-muted); font-size: .63rem; }
.app-time-popup__fields { display: flex; align-items: end; justify-content: center; gap: .35rem; padding: 1rem .2rem 1.1rem; }
.app-time-popup__fields label,
.app-datetime-popup__time label { display: grid; gap: .3rem; }
.app-time-popup__fields label span,
.app-datetime-popup__time label span { color: var(--app-foreground-muted); font-size: .58rem; font-weight: 760; letter-spacing: .05em; text-transform: uppercase; }
.app-time-popup__fields select,
.app-datetime-popup__time select { height: 2.75rem; box-sizing: border-box; padding-inline: .55rem 1.45rem; border: 1px solid var(--app-border); border-radius: .65rem; outline: 0; background: var(--app-surface-muted); color: var(--app-foreground); font: inherit; font-size: 1rem; font-weight: 780; font-variant-numeric: tabular-nums; cursor: pointer; }
.app-time-popup__fields select:hover,
.app-datetime-popup__time select:hover { border-color: var(--app-accent-border); }
.app-time-popup__fields select:focus-visible,
.app-datetime-popup__time select:focus-visible { border-color: var(--app-brand); box-shadow: 0 0 0 3px var(--app-brand-soft); }
.app-time-popup__fields b { padding-bottom: .72rem; color: var(--app-foreground-muted); }
.app-picker-popup__actions { display: grid; grid-template-columns: auto 1fr auto auto; align-items: center; gap: .35rem; padding-top: .7rem; border-top: 1px solid var(--app-grid-line); }
.app-picker-popup__button { min-height: 2.1rem; padding: .4rem .7rem; border: 1px solid transparent; border-radius: .55rem; font: inherit; font-size: .7rem; font-weight: 760; cursor: pointer; }
.app-picker-popup__button--quiet { background: transparent; color: var(--app-accent); }
.app-picker-popup__button--quiet:hover { background: var(--app-accent-soft); }
.app-picker-popup__button--primary { background: var(--app-brand); color: var(--app-on-brand); box-shadow: 0 .25rem .7rem var(--app-shadow-color); }
.app-picker-popup__button--primary:hover { filter: brightness(1.04); }
.app-picker-popup__button:disabled { cursor: not-allowed; opacity: .4; box-shadow: none; }
.app-picker-popup button:focus-visible { outline: 2px solid var(--app-focus-ring); outline-offset: 2px; }
.app-datetime-popup { width: min(21.25rem, calc(100vw - 1rem)); }
.app-datetime-popup__time { display: flex; align-items: end; gap: .3rem; margin-top: .65rem; padding: .65rem .2rem .75rem; border-top: 1px solid var(--app-grid-line); }
.app-datetime-popup__time-icon { display: grid; width: 2rem; height: 2.75rem; place-items: center; color: var(--app-accent); font-size: 1.15rem; }
.app-datetime-popup__time b { padding-bottom: .72rem; color: var(--app-foreground-muted); }
.app-datetime-popup__time select { height: 2.35rem; font-size: .82rem; }
.app-form-control__description,
.app-form-control__timezone,
.app-form-control__error {
color: var(--app-foreground-muted);
font-size: .7rem;
line-height: 1.45;
}
.app-form-control__timezone {
display: flex;
align-items: center;
gap: .35rem;
}
.app-form-control__timezone svg {
width: .85rem;
height: .85rem;
fill: none;
stroke: currentColor;
stroke-width: 1.7;
}
.app-form-control__error:empty { display: none; }
.app-form-control__error { color: var(--app-danger); }
.app-form-control:has(.app-form-control__input:invalid) .app-form-control__input-wrap { border-color: transparent; background: color-mix(in srgb, var(--app-danger-soft) 58%, var(--app-surface-muted)); box-shadow: inset .2rem 0 0 var(--app-danger); }
.app-form-control:has(.app-form-control__input:invalid) .app-form-control__input-wrap:focus-within { box-shadow: inset .2rem 0 0 var(--app-danger), 0 0 0 .22rem var(--app-danger-soft), 0 .55rem 1.25rem var(--app-shadow-color); }
.app-form-control__input:disabled { cursor: not-allowed; opacity: .58; }
.app-form-control:has(.app-form-control__input:disabled) .app-form-control__input-wrap { background: var(--app-surface-muted); box-shadow: none; }
fieldset.app-form-control { margin: 0; padding: 0; border: 0; }
.app-radio-group { display: grid; gap: .55rem; }
.app-radio-group--horizontal { grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); }
.app-choice { position: relative; display: flex; min-width: 0; align-items: flex-start; gap: .65rem; padding: .72rem; border: 1px solid var(--app-border); border-radius: .7rem; background: var(--app-surface); color: var(--app-foreground); cursor: pointer; transition: border-color .16s ease, background-color .16s ease, transform .16s ease; }
.app-choice:hover { border-color: var(--app-accent-border); background: var(--app-surface-hover); transform: translateY(-1px); }
.app-choice:has(.app-choice__native:focus-visible) { outline: 2px solid var(--app-focus-ring); outline-offset: 2px; }
.app-choice:has(.app-choice__native:checked) { border-color: var(--app-accent-border); background: var(--app-accent-soft); }
.app-choice:has(.app-choice__native:disabled) { cursor: not-allowed; opacity: .52; transform: none; }
.app-choice__native { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.app-choice__control { display: grid; width: 1.25rem; height: 1.25rem; box-sizing: border-box; margin-top: .02rem; place-items: center; flex: 0 0 auto; border: 1.5px solid var(--app-border); background: var(--app-background); color: var(--app-on-brand); transition: border-color .16s ease, background-color .16s ease, transform .2s cubic-bezier(.2,.9,.25,1.35), box-shadow .2s ease; }
.app-choice--checkbox .app-choice__control { border-radius: .36rem; }
.app-choice--radio .app-choice__control { border-radius: 50%; }
.app-choice__control svg { width: .9rem; height: .9rem; fill: none; stroke: currentColor; stroke-width: 2.3; stroke-linecap: round; stroke-linejoin: round; }
.app-choice__control svg path { stroke-dasharray: 18; stroke-dashoffset: 18; transition: stroke-dashoffset .22s ease .04s; }
.app-choice__control i { width: .55rem; height: .55rem; border-radius: 50%; background: currentColor; opacity: 0; transform: scale(.25); transition: opacity .14s ease, transform .2s cubic-bezier(.2,.9,.25,1.35); }
.app-choice__control .app-choice__mixed { width: .62rem; height: .12rem; border-radius: .2rem; background: currentColor; opacity: 0; transform: none; }
.app-choice__native:checked + .app-choice__control { border-color: var(--app-brand); background: var(--app-brand); transform: scale(1.05); box-shadow: 0 0 0 .28rem var(--app-brand-soft); }
.app-choice__native:checked + .app-choice__control svg path { stroke-dashoffset: 0; }
.app-choice__native:checked + .app-choice__control i { opacity: 1; transform: scale(1); }
.app-choice--indeterminate .app-choice__control { border-color: var(--app-brand); background: var(--app-brand); box-shadow: 0 0 0 .28rem var(--app-brand-soft); }
.app-choice--indeterminate .app-choice__control .app-choice__mixed { opacity: 1; }
.app-choice__content { display: grid; min-width: 0; gap: .2rem; }
.app-choice__content strong { font-size: .78rem; line-height: 1.3; }
.app-choice__content small { color: var(--app-foreground-muted); font-size: .68rem; line-height: 1.45; }
.app-form-control.has-error .app-choice { border-color: var(--app-danger-border); }
@media (forced-colors: active) {
.app-form-control__input-wrap { border-color: CanvasText; }
.app-form-control__input-wrap:focus-within { outline: 2px solid Highlight; outline-offset: 2px; }
}
@media (max-width: 24rem) {
.app-calendar-popup, .app-picker-popup { border-radius: .8rem; }
.app-calendar-popup__period { grid-template-columns: minmax(0, 1fr) 4.8rem; }
.app-datetime-popup__time { justify-content: center; }
.app-datetime-popup__time-icon { display: none; }
}
@media (prefers-reduced-motion: reduce) {
.app-form-control__input-wrap { transition: none; }
.app-choice, .app-choice__control, .app-choice__control svg path, .app-choice__control i { transition: none; }
.app-choice:hover { transform: none; }
}
.app-page {
border-top-left-radius: 20px;
background: var(--app-glass-surface) !important;
border-left: 2px solid var(--app-glass-border);
backdrop-filter: blur(16px) saturate(250%);
}
.glass-card {
background: var(--app-glass-surface-strong);
backdrop-filter: blur(20px) saturate(200%);
border: 1px solid var(--app-glass-border);
border-radius: var(--app-radius-lg);
box-shadow: 0 8px 32px var(--app-glass-shadow);
transition: background 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}
.glass-card:hover {
background: var(--app-surface-hover);
box-shadow: 0 12px 40px var(--app-glass-shadow);
}
.glass-container {
backdrop-filter: blur(20px) saturate(200%);
background: var(--app-glass-surface-strong);
border: 1px solid var(--app-glass-border);
box-shadow: 0 8px 32px var(--app-glass-shadow);
padding: 1rem 1.5rem;
border-radius: var(--app-radius-lg);
}
.glass-table {
width: 100%;
border-collapse: separate;
border-spacing: 0;
overflow: hidden;
background: var(--app-glass-surface-strong);
backdrop-filter: blur(20px) saturate(200%);
-webkit-backdrop-filter: blur(20px) saturate(200%);
border: 1px solid var(--app-glass-border);
border-radius: var(--app-radius-lg);
box-shadow: 0 8px 32px var(--app-glass-shadow);
}
.glass-table thead {
background: var(--app-glass-surface);
}
.glass-table th,
.glass-table td {
padding: 1rem 1.25rem;
text-align: left;
vertical-align: middle;
}
.glass-table th {
font-weight: 600;
}
.glass-table tbody tr {
transition: background 0.3s ease;
}
.glass-table tbody tr:hover {
background: var(--app-surface-hover);
}
.glass-table tbody tr + tr td {
border-top: 1px solid var(--app-glass-border);
}
.glass-table tbody td + td,
.glass-table thead td + td,
.glass-table thead th + th {
border-left: 1px solid var(--app-glass-border);
}
.glass-table caption {
padding: 1rem 1.25rem 0;
text-align: left;
color: inherit;
}
@media (max-width: 640px) {
.glass-table th,
.glass-table td {
padding: 0.875rem 1rem;
}
}
.margin-bottom {
margin-bottom: 1rem;
}
.identity-showcase-badge {
display: inline-flex;
align-self: flex-start;
padding: 0.45rem 0.85rem;
border-radius: 999px;
background: var(--identity-highlight-soft);
color: var(--identity-highlight);
font-size: 0.82rem;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.identity-showcase-points {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 1rem;
}
.identity-showcase-point {
display: grid;
gap: 0.45rem;
padding: 1rem;
border-radius: 22px;
border: 1px solid var(--identity-border);
background: var(--app-brand-soft);
}
.identity-showcase-point-title {
font-weight: 800;
color: var(--identity-text);
}
.identity-showcase-point-copy {
color: var(--identity-text-muted);
font-size: 0.92rem;
line-height: 1.6;
}
.identity-separator {
display: grid;
grid-template-columns: 1fr auto 1fr;
align-items: center;
gap: 0.9rem;
margin: 1.35rem 0;
}
.identity-separator span {
height: 1px;
background: var(--identity-divider);
}
.identity-separator p {
margin: 0;
color: var(--identity-text-muted);
font-size: 0.88rem;
letter-spacing: 0.08em;
text-transform: uppercase;
}
@media (max-width: 960px) {
.identity-showcase-points {
grid-template-columns: 1fr;
}
}
@media (max-width: 640px) {
.identity-form-actions {
align-items: stretch;
}
.identity-form-actions ::deep .app-button {
width: 100%;
}
}
:root {
/*
* Public color contract.
*
* Consuming applications override these semantic roles with explicit
* light-dark() values taken from the product identity. Components must
* consume roles from this list instead of deriving a palette from one hue.
*/
/* Product identity and interactive emphasis. */
--app-brand: light-dark(#0f6cbd, #62abf5);
--app-on-brand: light-dark(#ffffff, #07181d);
--app-brand-secondary: light-dark(#107c10, #54c754);
--app-accent: var(--app-brand);
--app-accent-soft: light-dark(rgb(15 108 189 / .12), rgb(98 171 245 / .18));
--app-accent-border: light-dark(#8bbce8, #326b9f);
--app-brand-soft: light-dark(rgb(15 108 189 / .10), rgb(98 171 245 / .16));
--app-brand-secondary-soft: light-dark(rgb(16 124 16 / .11), rgb(84 199 84 / .17));
/* Page, panel, and translucent surfaces. */
--app-background: light-dark(#f7f9fb, #101418);
--app-surface: light-dark(#ffffff, #191f24);
--app-surface-muted: light-dark(#f1f4f7, #222a31);
--app-surface-hover: light-dark(#edf2f6, #303a43);
--app-glass-surface: light-dark(rgb(255 255 255 / .58), rgb(25 31 36 / .64));
--app-glass-surface-strong: light-dark(rgb(255 255 255 / .78), rgb(25 31 36 / .82));
--app-glass-border: light-dark(rgb(23 33 43 / .14), rgb(229 238 246 / .18));
--app-glass-shadow: light-dark(rgb(15 23 42 / .12), rgb(0 0 0 / .38));
/* Readable content and structural lines. */
--app-foreground: light-dark(#17212b, #edf3f8);
--app-foreground-muted: light-dark(#5f6b7a, #afbbc5);
--app-border: light-dark(#d7dde5, #38434d);
--app-grid-line: light-dark(rgb(23 33 43 / .08), rgb(237 243 248 / .08));
--app-shadow-color: light-dark(rgb(15 23 42 / .12), rgb(0 0 0 / .34));
/* Feedback roles include an explicit soft surface and border. */
--app-success: light-dark(#107c10, #54c754);
--app-success-soft: light-dark(#edf8ed, #173619);
--app-success-border: light-dark(#8bc98b, #397b3d);
--app-warning: light-dark(#8a4f00, #f2b84b);
--app-warning-soft: light-dark(#fff5df, #3b2b10);
--app-warning-border: light-dark(#d8ae65, #8b692b);
--app-danger: light-dark(#b42318, #ff8b83);
--app-on-danger: light-dark(#fff, #1b0b0a);
--app-danger-soft: light-dark(#fff0ef, #421c1a);
--app-danger-border: light-dark(#e3a29e, #99524d);
}
/* Application baseline. This deliberately replaces a framework-owned reboot so
shared layouts have a predictable document scroll and form inheritance. */
html {
box-sizing: border-box;
min-height: 100%;
scroll-behavior: smooth;
text-size-adjust: 100%;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
body,
h1,
h2,
h3,
h4,
h5,
h6,
p,
figure,
blockquote,
dl,
dd {
margin: 0;
}
ul[role="list"],
ol[role="list"] {
padding: 0;
list-style: none;
}
img,
picture,
svg,
canvas {
display: block;
max-width: 100%;
}
button,
input,
select,
textarea {
margin: 0;
color: inherit;
font: inherit;
}
button,
select {
text-transform: none;
}
button,
[type="button"],
[type="reset"],
[type="submit"] {
appearance: button;
}
textarea {
resize: vertical;
}
:root {
/* Primitive tokens: shared across every consuming application. */
--app-font-body: "Source Sans 3", "Sarabun", "Segoe UI Variable", "Segoe UI", sans-serif;
--app-font-heading: "Figtree", "IBM Plex Sans Thai", "Segoe UI Variable", sans-serif;
--app-font-mono: "Cascadia Code", "SFMono-Regular", Consolas, monospace;
--app-type-xs: .75rem;
--app-type-sm: .875rem;
--app-type-body: 1rem;
--app-type-lead: clamp(1.04rem, 1.45vw, 1.22rem);
--app-type-title: clamp(2.15rem, 4vw, 3.5rem);
--app-type-display: clamp(2.65rem, 4vw, 4rem);
--app-space-1: .25rem;
--app-space-2: .5rem;
--app-space-3: .75rem;
--app-space-4: 1rem;
--app-space-5: 1.25rem;
--app-space-6: 1.5rem;
--app-space-8: 2rem;
--app-space-10: 2.5rem;
--app-space-12: 3rem;
--app-space-14: 3.5rem;
--app-space-16: 4rem;
--app-space-18: 4.5rem;
--app-space-24: 6rem;
--app-radius-sm: .5rem;
--app-radius-md: .75rem;
--app-radius-lg: 1rem;
--app-radius-xl: 1.5rem;
--app-radius-round: 999px;
--app-shadow-sm: 0 1px 2px rgb(15 23 42 / .06);
--app-shadow-md: 0 12px 32px rgb(15 23 42 / .10);
--app-shadow-lg: 0 24px 64px rgb(15 23 42 / .14);
--app-duration-fast: 120ms;
--app-duration-normal: 220ms;
--app-duration-slow: 420ms;
--app-page-padding-block: .75rem 1.5rem;
--app-page-padding-inline: 1.5rem;
--app-page-gap: var(--app-space-4);
--app-content-max-width: none;
--app-layout-gutter: clamp(1.25rem, 4vw, 3rem);
--app-marketing-max-width: 76rem;
}
html body {
--fontFamilyBase: var(--app-font-body);
margin: 0;
height: auto;
min-height: 100dvh;
overflow-x: clip;
overflow-y: auto;
background: var(--app-background);
color: var(--app-foreground);
font-family: var(--app-font-body);
font-optical-sizing: auto;
font-size: var(--app-type-body);
line-height: var(--type-ramp-base-line-height, 1.5);
}
::selection {
background: var(--app-accent-soft);
}
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
outline: 2px solid var(--app-focus-ring);
outline-offset: 2px;
}
@media (forced-colors: active) {
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
outline-color: Highlight;
}
}
body h1,
body h2,
body h3,
body h4,
body h5,
body h6,
body [role="heading"],
body .app-heading {
font-family: var(--app-font-heading);
text-wrap: balance;
}
h1 {
font-size: clamp(1.35rem, 2.4vw, 1.85rem);
font-weight: 750;
line-height: 1.2;
letter-spacing: -.015em;
}
h2 {
font-size: clamp(1.15rem, 1.9vw, 1.5rem);
font-weight: 700;
line-height: 1.3;
letter-spacing: -.01em;
}
h3 {
font-size: clamp(1rem, 1.5vw, 1.2rem);
font-weight: 700;
line-height: 1.35;
}
code,
kbd,
pre,
samp {
font-family: var(--app-font-mono);
}
/* Shared visual baseline for the QuickGrid-backed AppGrid. AppGridShell adds
command-bar, surface, state, scrolling, and pagination composition. */
.app-grid {
color: var(--app-foreground);
}
.app-grid thead {
background: var(--app-glass-surface);
}
.app-grid th {
color: var(--app-foreground-muted);
font-size: .75rem;
font-weight: 700;
letter-spacing: .04em;
text-transform: uppercase;
}
.app-grid td {
vertical-align: middle;
}
.app-page {
box-sizing: border-box;
display: flex;
flex: 1 1 auto;
align-self: stretch;
flex-direction: column;
gap: var(--app-page-gap);
width: 100%;
max-width: var(--app-content-max-width);
min-width: 0;
min-height: 0;
padding: var(--app-page-padding-block) var(--app-page-padding-inline);
outline: none;
}
.app-page:focus-visible {
box-shadow: inset 0 0 0 2px var(--app-accent);
}
.app-page__feedback:empty,
.app-page__breadcrumbs:empty,
.app-page__heading:empty {
display: none;
}
.app-page__intro {
display: flex;
flex: 0 0 auto;
flex-direction: column;
gap: .35rem;
min-width: 0;
margin: calc(-1 * var(--app-page-padding-block)) calc(-1 * var(--app-page-padding-inline)) 0;
padding: .8rem var(--app-page-padding-inline) .9rem;
border-bottom: 1px solid var(--app-border);
background:
linear-gradient(105deg,
var(--app-brand-soft) 0%,
var(--app-surface) 52%,
var(--app-brand-secondary-soft) 100%);
}
.app-page__breadcrumbs {
display: flex;
min-height: 1.75rem;
align-items: center;
font-family: var(--app-font-body);
font-size: .78rem;
line-height: 1.35;
}
.app-page__heading {
min-width: 0;
font-family: var(--app-font-body);
}
.app-page__body {
display: flex;
flex: 1 1 auto;
flex-direction: column;
gap: var(--app-page-gap);
min-width: 0;
min-height: 0;
}
/* Compatibility contracts for pages that have not yet moved to the Razor
primitives. New pages should prefer PageHeading, Toolbar, StatusPanel, and
AppGridShell. */
.app-page-heading {
display: flex;
min-width: 0;
align-items: center;
gap: .625rem;
}
.app-page-heading h1 {
margin: 0;
}
.app-grid-shell {
flex: 1 1 0;
min-width: 0;
min-height: 0;
overflow: auto;
box-sizing: border-box;
padding: 0;
border: 1px solid var(--app-glass-border);
border-radius: var(--app-radius-lg);
background: var(--app-glass-surface-strong);
box-shadow: var(--app-shadow-md);
backdrop-filter: blur(20px) saturate(180%);
-webkit-backdrop-filter: blur(20px) saturate(180%);
}
.app-grid-shell .app-grid {
width: 100%;
min-width: max-content;
}
.app-grid-shell .app-grid thead {
background: var(--app-glass-surface);
}
.ui-state {
display: grid;
max-width: 42rem;
min-height: 14rem;
margin: 1rem auto;
padding: clamp(1.5rem, 4vw, 2.5rem);
place-items: center;
align-content: center;
gap: .75rem;
border: 1px solid var(--app-border);
border-radius: var(--app-radius-lg);
background: var(--app-surface);
color: var(--app-foreground);
text-align: center;
}
.ui-state h2,
.ui-state p {
margin: 0;
}
.ui-state p {
max-width: 34rem;
color: var(--app-foreground-muted);
line-height: 1.65;
}
.ui-state--success {
border-color: var(--app-success-border);
}
.ui-state--warning {
border-color: var(--app-warning-border);
}
.ui-state--error {
border-color: var(--app-danger-border);
}
.text-danger {
color: var(--app-danger);
}
@media (max-width: 48rem) {
:root {
--app-page-padding-block: .75rem 1rem;
--app-page-padding-inline: .75rem;
--app-page-gap: .75rem;
}
.app-grid-shell {
border-radius: .75rem;
}
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
scroll-behavior: auto !important;
transition-duration: .01ms !important;
animation-duration: .01ms !important;
animation-iteration-count: 1 !important;
}
}
/* A SectionOutlet can retain a Blazor placeholder without rendering a page heading. */
.app-shell__page-heading:has(> .application-page-heading:not(:has(.application-page-heading__visual > *))) {
display: none;
}
