:root { --font-sans: "Inter", "Inter var", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", sans-serif; --font-mono: "DM Mono", "JetBrains Mono", "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", monospace; --color-canvas: #f5f6f8; --color-surface: #ffffff; --color-surface-subtle: #f1f3f7; --color-border: #d0d5dd; --color-border-strong: #9aa2af; --color-heading: #101828; --color-text: #1f2933; --color-text-muted: #52616b; --color-link: #2563eb; --color-link-hover: #1d4ed8; --color-accent: #2563eb; --color-accent-strong: #1e3faa; --color-accent-contrast: #ffffff; --color-success-text: #0f5132; --color-success-bg: #d1fadf; --color-error-text: #b42318; --color-error-bg: #ffe3e3; --color-info-text: #0f609b; --color-info-bg: #d6ecff; --color-danger: #dc2626; --shadow-soft: 0 10px 30px rgba(15, 23, 42, 0.08); --radius-none: 0; --radius-sm: 4px; --radius-md: 6px; --radius-lg: 10px; --space-xxs: 0.25rem; --space-xs: 0.5rem; --space-sm: 0.75rem; --space-md: 1rem; --space-lg: 1.5rem; --space-xl: 2.25rem; --space-xxl: 3.5rem; --layout-max-width: 1080px; --layout-padding: clamp(1.5rem, 3vw + 1rem, 3.25rem); --transition-base: 160ms ease; } @media (prefers-color-scheme: dark) { :root { --color-canvas: #0f172a; --color-surface: #141b2f; --color-surface-subtle: #1b243b; --color-border: #25304a; --color-border-strong: #3d4d6b; --color-heading: #f8fafc; --color-text: #e2e8f0; --color-text-muted: #94a3b8; --color-link: #60a5fa; --color-link-hover: #93c5fd; --color-accent: #60a5fa; --color-accent-strong: #3b82f6; --color-accent-contrast: #0b1120; --color-success-text: #34d399; --color-success-bg: #1a4d2e; --color-error-text: #fca5a5; --color-error-bg: #4a1f1f; --color-info-text: #bae6fd; --color-info-bg: #1e3a5f; --color-danger: #f87171; --shadow-soft: 0 0 0 #000000; } } *, *::before, *::after { box-sizing: border-box; } html { height: 100%; background: var(--color-canvas); } body { height: 100%; margin: 0; font-family: var(--font-sans); background: none; color: var(--color-text); line-height: 1.55; -webkit-font-smoothing: antialiased; } body, #app, #admin-app { display: flex; flex-direction: column; min-height: 100vh; } #app, #admin-app { flex: 1; } a, a:visited { color: var(--color-link); text-decoration: none; } a:hover, a:focus-visible { color: var(--color-link-hover); text-decoration: underline; } a:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; border-radius: var(--radius-sm); } .app-shell { flex: 1; display: flex; flex-direction: column; min-height: 100vh; } .app-main { flex: 1; display: flex; flex-direction: column; } .view-root { flex: 1; width: 100%; display: flex; flex-direction: column; gap: 2rem; padding: var(--layout-padding); box-sizing: border-box; margin: 0 auto; width: min(100%, var(--layout-max-width)); } .view-root--wide { width: min(100%, 1200px); } .view-root--narrow { max-width: 540px; } .view-header { display: flex; flex-direction: column; gap: 0.75rem; } .view-header h1 { margin: 0; font-weight: 600; color: var(--color-heading); } .view-lede { margin: 0; color: var(--color-text-muted); font-size: 1rem; } .section-block { display: flex; flex-direction: column; gap: 1rem; } .section-block h2 { margin: 0; font-size: clamp(1.25rem, 1.5vw + 1rem, 1.65rem); font-weight: 600; color: var(--color-heading); } .section-body { display: flex; flex-direction: column; gap: 1rem; } .button-row { display: flex; flex-wrap: wrap; gap: 0.75rem; justify-content: flex-start; } .surface { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: var(--space-lg); box-shadow: var(--shadow-soft); } .surface--tight { padding: var(--space-md); } button { font-family: inherit; font-size: 1rem; font-weight: 500; border-radius: var(--radius-sm); border: 1px solid transparent; padding: 0.65rem 1.1rem; cursor: pointer; transition: all var(--transition-base); display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem; background: var(--color-surface); color: var(--color-text); } button:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; } button:disabled { cursor: not-allowed; filter: opacity(0.6); } .btn-primary { background: var(--color-accent); color: var(--color-accent-contrast); border-color: var(--color-accent); box-shadow: var(--shadow-soft); } .btn-primary:hover:not(:disabled) { background: var(--color-accent-strong); border-color: var(--color-accent-strong); } .btn-secondary { background: transparent; color: var(--color-text); border-color: var(--color-border); } .btn-secondary:hover:not(:disabled) { border-color: var(--color-border-strong); background: var(--color-surface-subtle); } .btn-danger { background: var(--color-danger); color: var(--color-accent-contrast); border-color: transparent; } .btn-danger:hover:not(:disabled) { filter: brightness(0.92); } input[type="text"], input[type="search"], input[type="email"], textarea, select { font: inherit; width: 100%; padding: 0.65rem 0.75rem; border-radius: var(--radius-sm); border: 1px solid var(--color-border); background: var(--color-surface); color: var(--color-text); transition: border-color var(--transition-base), box-shadow var(--transition-base); } input:focus-visible, textarea:focus-visible, select:focus-visible { border-color: var(--color-accent); box-shadow: 0 0 0 3px #c7d2fe; outline: none; } label { display: flex; flex-direction: column; gap: 0.5rem; color: var(--color-text); } p { margin: 0; color: var(--color-text); } small { color: var(--color-text-muted); } .table-wrapper { overflow-x: auto; background: var(--color-surface); border: 1px solid var(--color-border); } table { width: 100%; border-collapse: collapse; font-size: 0.95rem; } thead tr { background: var(--color-surface-subtle); color: var(--color-text-muted); } td, th { padding: 0.65rem 0.75rem; border-bottom: 1px solid var(--color-border); text-align: left; } .center { text-align: center; } .badge { display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.2rem 0.6rem; border-radius: var(--radius-sm); background: var(--color-surface-subtle); border: 1px solid var(--color-border); color: var(--color-text-muted); font-size: 0.75rem; } .global-status { position: fixed; top: 1.5rem; left: 50%; transform: translateX(-50%); z-index: 1200; min-width: min(520px, calc(100vw - 2rem)); display: none; } .global-status .status { display: flex; align-items: center; justify-content: center; padding: 0.85rem 1.25rem; border-radius: var(--radius-sm); border-width: 1px; border-style: solid; background: var(--color-surface); box-shadow: var(--shadow-soft); font-weight: 550; } .status.info { border-color: #3b82f6; color: var(--color-info-text); background: var(--color-info-bg); } .status.success { border-color: #16a34a; color: var(--color-success-text); background: var(--color-success-bg); } .status.error { border-color: #dc2626; color: var(--color-error-text); background: var(--color-error-bg); } .dialog-overlay { position: fixed; inset: 0; background: #1e293b; backdrop-filter: blur(6px); z-index: 1100; display: flex; align-items: center; justify-content: center; padding: 1.5rem; } .device-dialog, .modal { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-md); width: min(520px, 100%); max-height: calc(100vh - 3rem); overflow-y: auto; padding: 1.75rem; box-shadow: var(--shadow-soft); color: var(--color-text); } .qr-container { display: flex; flex-direction: column; align-items: center; gap: 0.75rem; text-align: center; color: var(--color-text-muted); } .qr-code { border: 1px solid var(--color-border); padding: 0.75rem; background: var(--color-surface); } .link-container, .token-display, .token-info { background: var(--color-surface-subtle); border: 1px solid var(--color-border); border-radius: var(--radius-sm); padding: 0.75rem; color: var(--color-text); } :root { --card-width: 22rem; } .record-list, .credential-list, .session-list { width: 100%; display: grid; grid-auto-flow: row; grid-template-columns: repeat(auto-fit, var(--card-width)); justify-content: start; gap: 1rem 1.25rem; align-items: stretch; margin: 0 auto; max-width: calc(var(--card-width) * 4 + 3 * 1.25rem); } @media (max-width: 1100px) { .record-list, .credential-list, .session-list { max-width: calc(var(--card-width) * 3 + 2 * 1.25rem); } } @media (max-width: 720px) { .record-list { display: flex; flex-direction: column; max-width: 100%; } } .record-item, .credential-item, .session-item { display: flex; flex-direction: column; gap: 0.75rem; padding: 1rem; border: 1px solid var(--color-border); border-radius: var(--radius-md); background: var(--color-surface); height: 100%; transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease; position: relative; } .record-item:hover, .credential-item:hover, .session-item:hover { border-color: var(--color-border-strong); box-shadow: 0 10px 24px rgba(15, 23, 42, 0.12); transform: translateY(-1px); } .record-item.is-current, .credential-item.current-session, .session-item.is-current { border-color: var(--color-accent); } .item-top { display: flex; align-items: center; gap: 1rem; } .item-icon { width: 40px; height: 40px; display: grid; place-items: center; background: var(--color-surface-subtle, transparent); border-radius: var(--radius-sm); border: 1px solid var(--color-border); flex-shrink: 0; } .auth-icon { border-radius: var(--radius-sm); } .item-title { flex: 1; margin: 0; font-size: 1rem; font-weight: 600; color: var(--color-heading); } .item-actions { flex-shrink: 0; display: flex; gap: 0.5rem; align-items: center; } .item-actions .badge + .btn-card-delete { margin-left: 0.25rem; } .item-actions .badge + .badge { margin-left: 0.25rem; } .item-details { margin-left: calc(40px + 1rem); display: flex; flex-direction: column; gap: 0.5rem; } .credential-dates { display: grid; grid-auto-flow: row; grid-template-columns: 7rem 1fr; gap: 0.35rem 0.5rem; font-size: 0.75rem; color: var(--color-text-muted); align-items: center; } .session-dates { display: grid; grid-auto-flow: row; grid-template-columns: 7rem 1fr; gap: 0.35rem 0.5rem; font-size: 0.75rem; color: var(--color-text-muted); align-items: center; } .date-label { font-weight: 500; color: inherit; } .date-value { color: var(--color-text); } .btn-card-delete { background: transparent; border: none; color: var(--color-danger); padding: 0.35rem 0.5rem; font-size: 1.05rem; line-height: 1; border-radius: var(--radius-sm); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; } .btn-card-delete:hover:not(:disabled) { background: #fee; } .btn-card-delete:disabled { filter: opacity(0.4); cursor: not-allowed; } .session-emoji { font-size: 1.2rem; } .badge { padding: 0.2rem 0.5rem; border-radius: var(--radius-sm); font-size: 0.8rem; font-weight: 500; } .badge-current { background: var(--color-accent); color: var(--color-accent-contrast); box-shadow: 0 0 0 1px var(--color-accent) inset; } .badge:not(.badge-current) { background: var(--color-surface-subtle); color: var(--color-text-muted); border: 1px solid var(--color-border); } .session-meta-info { font-size: 0.75rem; color: var(--color-text-muted); font-family: monospace; } .empty-state { text-align: center; padding: var(--space-lg); color: var(--color-text-muted); } .empty-state p { margin: 0; } .user-info { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-sm); padding: 1.1rem 1.25rem; display: grid; grid-template-columns: auto 1fr; gap: 0.75rem 1.25rem; } .user-info h3 { margin: 0; grid-column: span 2; display: flex; align-items: center; gap: 0.5rem; font-size: 1.15rem; font-weight: 600; } .user-info span { text-align: left; color: var(--color-text); } .toggle-link { color: var(--color-link); cursor: pointer; } .toggle-link:hover { color: var(--color-link-hover); } .token-info code { font-family: var(--font-mono); } @media (max-width: 720px) { .view-root { padding: clamp(1rem, 3vw + 0.75rem, 2rem); gap: 1.75rem; } .credential-dates { grid-auto-flow: row; grid-template-columns: auto auto; } button { width: 100%; } .button-row { flex-direction: column; } .global-status { top: 1rem; } } .dialog-backdrop { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: #334155; backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; z-index: 1000; } .dialog-container { max-width: 90vw; max-height: 90vh; overflow-y: auto; } .dialog-content { flex: none; width: 100%; max-width: 480px; padding: 2rem; background: var(--color-surface); border-radius: var(--radius-lg); box-shadow: 0 20px 60px #1e293b; border: 1px solid var(--color-border); } .dialog-content--wide { max-width: 540px; } .dialog-content--narrow { max-width: 420px; } @media (max-width: 720px) { .dialog-content { padding: 1.5rem; } }