SPB Git

spb/chat-spboucher Public

Private universal chat interface over the OpenRouter ecosystem — 400+ models, branching, streaming, usage tracking. Next.js 16 + SQLite, PWA, deployed on m4m64a at chat.spboucher.ai

TypeScript 78.8% CSS 15.1% JavaScript 4.9% Shell 1.2%
24.1 KB · 1,373 lines css
Raw Blame History
1/* Author: Simon-Pierre Boucher2   Contact: contact@spboucher.ai3   Project: chat.spboucher.ai45   Design system — "Instrument Panel".6   Dark-first, one accent for "alive" (signal teal), one for "cost" (amber).7   Mobile-first: base styles target ~390px, enhanced upward. */89:root,10:root[data-theme="dark"] {11  --ink-950: #0e1116;12  --ink-900: #151a22;13  --ink-850: #1a212b;14  --ink-700: #2a3240;15  --fog-300: #aab4c3;16  --fog-050: #eef2f7;17  --signal-500: #3fb6a8;18  --signal-600: #2f9a8e;19  --signal-alpha: rgba(63, 182, 168, 0.14);20  --amber-500: #e0a458;21  --amber-alpha: rgba(224, 164, 88, 0.15);22  --danger: #d97b7b;2324  --surface: var(--ink-950);25  --surface-raised: var(--ink-900);26  --surface-raised-2: var(--ink-850);27  --border: var(--ink-700);28  --text: var(--fog-050);29  --text-dim: var(--fog-300);30  --user-bubble: #1d2634;3132  --sheet-shadow: 0 -12px 48px rgba(0, 0, 0, 0.5);33  --card-shadow: 0 2px 16px rgba(0, 0, 0, 0.35);34}3536:root[data-theme="light"] {37  --ink-950: #f6f8fa;38  --ink-900: #ffffff;39  --ink-850: #eef1f5;40  --ink-700: #d4dbe4;41  --fog-300: #5b6675;42  --fog-050: #171d26;43  --signal-500: #2b9a8e;44  --signal-600: #23857a;45  --signal-alpha: rgba(43, 154, 142, 0.12);46  --amber-500: #b97f35;47  --amber-alpha: rgba(185, 127, 53, 0.13);48  --danger: #b54545;4950  --surface: var(--ink-950);51  --surface-raised: var(--ink-900);52  --surface-raised-2: var(--ink-850);53  --border: var(--ink-700);54  --text: var(--fog-050);55  --text-dim: var(--fog-300);56  --user-bubble: #e7edf4;5758  --sheet-shadow: 0 -12px 48px rgba(23, 29, 38, 0.18);59  --card-shadow: 0 2px 16px rgba(23, 29, 38, 0.08);60}6162@media (prefers-color-scheme: light) {63  :root:not([data-theme]) {64    --ink-950: #f6f8fa;65    --ink-900: #ffffff;66    --ink-850: #eef1f5;67    --ink-700: #d4dbe4;68    --fog-300: #5b6675;69    --fog-050: #171d26;70    --signal-500: #2b9a8e;71    --signal-600: #23857a;72    --signal-alpha: rgba(43, 154, 142, 0.12);73    --amber-500: #b97f35;74    --amber-alpha: rgba(185, 127, 53, 0.13);75    --danger: #b54545;76    --surface: var(--ink-950);77    --surface-raised: var(--ink-900);78    --surface-raised-2: var(--ink-850);79    --border: var(--ink-700);80    --text: var(--fog-050);81    --text-dim: var(--fog-300);82    --user-bubble: #e7edf4;83    --sheet-shadow: 0 -12px 48px rgba(23, 29, 38, 0.18);84    --card-shadow: 0 2px 16px rgba(23, 29, 38, 0.08);85  }86}8788* {89  box-sizing: border-box;90}9192html,93body {94  margin: 0;95  padding: 0;96  height: 100%;97}9899body {100  background: var(--surface);101  color: var(--text);102  font-family: var(--font-ui), Inter, -apple-system, system-ui, sans-serif;103  font-size: 16px;104  line-height: 1.6;105  -webkit-font-smoothing: antialiased;106  overscroll-behavior-y: none;107}108109code,110kbd,111pre,112.mono {113  font-family: var(--font-mono), "Berkeley Mono", "JetBrains Mono", ui-monospace, monospace;114}115116button {117  font-family: inherit;118  color: inherit;119  background: none;120  border: none;121  cursor: pointer;122  padding: 0;123}124125button:focus-visible,126a:focus-visible,127input:focus-visible,128textarea:focus-visible,129[tabindex]:focus-visible {130  outline: 2px solid var(--signal-500);131  outline-offset: 2px;132  border-radius: 4px;133}134135input,136textarea {137  font-family: inherit;138  font-size: inherit;139  color: inherit;140}141142a {143  color: var(--signal-500);144}145146::selection {147  background: var(--signal-alpha);148}149150/* ---------- App shell ---------- */151152.app {153  display: flex;154  height: 100dvh;155  overflow: hidden;156}157158.main {159  flex: 1;160  display: flex;161  flex-direction: column;162  min-width: 0;163  position: relative;164}165166/* ---------- Top bar ---------- */167168.topbar {169  display: flex;170  align-items: center;171  gap: 10px;172  padding: 10px 14px;173  padding-top: calc(10px + env(safe-area-inset-top));174  border-bottom: 1px solid var(--border);175  background: var(--surface);176  min-height: 54px;177}178179.topbar-title {180  flex: 1;181  font-weight: 600;182  font-size: 15px;183  letter-spacing: -0.01em;184  white-space: nowrap;185  overflow: hidden;186  text-overflow: ellipsis;187}188189.icon-btn {190  display: inline-flex;191  align-items: center;192  justify-content: center;193  width: 44px;194  height: 44px;195  border-radius: 10px;196  color: var(--text-dim);197  flex: none;198}199200.icon-btn:hover {201  background: var(--surface-raised);202  color: var(--text);203}204205/* ---------- Sidebar / drawer ---------- */206207.sidebar {208  width: 300px;209  flex: none;210  background: var(--surface-raised);211  border-right: 1px solid var(--border);212  display: flex;213  flex-direction: column;214  padding-top: env(safe-area-inset-top);215}216217.sidebar-header {218  display: flex;219  align-items: center;220  gap: 8px;221  padding: 14px;222}223224.wordmark {225  font-family: var(--font-mono), monospace;226  font-size: 13px;227  font-weight: 600;228  letter-spacing: 0.02em;229  color: var(--text);230  flex: 1;231  user-select: none;232}233234.wordmark .tld {235  color: var(--signal-500);236}237238.new-chat-btn {239  display: flex;240  align-items: center;241  gap: 8px;242  margin: 0 14px 10px;243  padding: 11px 14px;244  border-radius: 10px;245  border: 1px solid var(--border);246  background: var(--surface);247  font-weight: 500;248  font-size: 14px;249  transition: border-color 0.15s;250}251252.new-chat-btn:hover {253  border-color: var(--signal-500);254}255256.conv-list {257  flex: 1;258  overflow-y: auto;259  padding: 0 8px 14px;260}261262.conv-item {263  display: flex;264  align-items: center;265  gap: 8px;266  width: 100%;267  text-align: left;268  padding: 10px 10px;269  border-radius: 9px;270  font-size: 14px;271  color: var(--text-dim);272  margin-bottom: 1px;273}274275.conv-item.active {276  background: var(--surface-raised-2);277  color: var(--text);278}279280.conv-item:hover {281  background: var(--surface-raised-2);282}283284.conv-item .conv-title {285  flex: 1;286  white-space: nowrap;287  overflow: hidden;288  text-overflow: ellipsis;289}290291.conv-item .conv-del {292  opacity: 0;293  color: var(--text-dim);294  width: 28px;295  height: 28px;296  border-radius: 6px;297  display: inline-flex;298  align-items: center;299  justify-content: center;300  flex: none;301}302303.conv-item:hover .conv-del,304.conv-item.active .conv-del {305  opacity: 1;306}307308.conv-item .conv-del:hover {309  color: var(--danger);310  background: var(--surface);311}312313.sidebar-footer {314  border-top: 1px solid var(--border);315  padding: 10px 14px calc(10px + env(safe-area-inset-bottom));316  display: flex;317  gap: 6px;318}319320.sidebar-footer .foot-btn {321  flex: 1;322  display: flex;323  align-items: center;324  gap: 8px;325  padding: 9px 10px;326  border-radius: 8px;327  font-size: 13px;328  color: var(--text-dim);329}330331.sidebar-footer .foot-btn:hover {332  background: var(--surface-raised-2);333  color: var(--text);334}335336/* Mobile: sidebar becomes an off-canvas drawer */337@media (max-width: 1023px) {338  .sidebar {339    position: fixed;340    inset: 0 auto 0 0;341    z-index: 40;342    transform: translateX(-100%);343    transition: transform 0.25s cubic-bezier(0.32, 0.72, 0, 1);344    width: min(84vw, 320px);345    box-shadow: none;346  }347348  .sidebar.open {349    transform: translateX(0);350    box-shadow: 24px 0 64px rgba(0, 0, 0, 0.4);351  }352353  .drawer-scrim {354    position: fixed;355    inset: 0;356    z-index: 39;357    background: rgba(0, 0, 0, 0.45);358    opacity: 0;359    pointer-events: none;360    transition: opacity 0.25s;361  }362363  .drawer-scrim.open {364    opacity: 1;365    pointer-events: auto;366  }367}368369@media (min-width: 1024px) {370  .drawer-scrim {371    display: none;372  }373374  .topbar .menu-btn {375    display: none;376  }377}378379/* ---------- Messages ---------- */380381.message-scroll {382  flex: 1;383  overflow-y: auto;384  overscroll-behavior: contain;385  scroll-behavior: smooth;386}387388@media (prefers-reduced-motion: reduce) {389  .message-scroll {390    scroll-behavior: auto;391  }392  * {393    animation-duration: 0.001s !important;394    transition-duration: 0.001s !important;395  }396}397398.message-column {399  max-width: 780px;400  margin: 0 auto;401  padding: 20px 16px 24px;402  display: flex;403  flex-direction: column;404  gap: 22px;405}406407.empty-state {408  margin: auto;409  text-align: center;410  padding: 40px 24px;411  color: var(--text-dim);412}413414.empty-state .glyph {415  font-family: var(--font-mono), monospace;416  font-size: 28px;417  color: var(--signal-500);418  margin-bottom: 14px;419}420421.empty-state h2 {422  color: var(--text);423  font-size: 17px;424  font-weight: 600;425  margin: 0 0 6px;426}427428.empty-state p {429  font-size: 14px;430  margin: 0;431}432433/* User message: compact right-aligned card */434.msg-user {435  align-self: flex-end;436  max-width: 85%;437  background: var(--user-bubble);438  border-radius: 14px 14px 4px 14px;439  padding: 10px 14px;440  white-space: pre-wrap;441  word-break: break-word;442  font-size: 16px;443}444445.msg-user.pending {446  opacity: 0.6;447}448449/* Assistant message: full-width block with slim attribution header */450.msg-assistant {451  display: flex;452  flex-direction: column;453  gap: 6px;454  min-width: 0;455}456457.msg-attribution {458  display: flex;459  align-items: center;460  gap: 8px;461  font-family: var(--font-mono), monospace;462  font-size: 11.5px;463  color: var(--text-dim);464  flex-wrap: wrap;465}466467.msg-attribution .model-name {468  color: var(--text);469  font-weight: 500;470}471472.msg-attribution .live-dot {473  width: 7px;474  height: 7px;475  border-radius: 50%;476  background: var(--signal-500);477  animation: pulse 1.4s ease-in-out infinite;478}479480@keyframes pulse {481  0%,482  100% {483    opacity: 1;484  }485  50% {486    opacity: 0.25;487  }488}489490.cost-chip {491  color: var(--amber-500);492  background: var(--amber-alpha);493  padding: 1px 7px;494  border-radius: 6px;495  font-size: 11px;496}497498.msg-body {499  font-size: 16.5px;500  line-height: 1.62;501  word-break: break-word;502  min-width: 0;503}504505.msg-body > *:first-child {506  margin-top: 0;507}508509.msg-body > *:last-child {510  margin-bottom: 0;511}512513.msg-error {514  color: var(--danger);515  font-size: 14px;516  border: 1px solid color-mix(in srgb, var(--danger) 35%, transparent);517  border-radius: 10px;518  padding: 10px 14px;519  background: color-mix(in srgb, var(--danger) 7%, transparent);520}521522.streaming-caret::after {523  content: "";524  display: inline-block;525  width: 8px;526  height: 17px;527  margin-left: 3px;528  vertical-align: text-bottom;529  background: var(--signal-500);530  border-radius: 2px;531  animation: pulse 1.1s ease-in-out infinite;532}533534.reasoning-block {535  border-left: 2px solid var(--border);536  padding: 2px 0 2px 12px;537  color: var(--text-dim);538  font-size: 13.5px;539  margin-bottom: 8px;540}541542.reasoning-block summary {543  cursor: pointer;544  font-family: var(--font-mono), monospace;545  font-size: 11.5px;546  user-select: none;547  list-style: none;548}549550.reasoning-block summary::-webkit-details-marker {551  display: none;552}553554/* Message actions: tap-friendly row, never hover-only */555.msg-actions {556  display: flex;557  align-items: center;558  gap: 4px;559  margin-top: 2px;560}561562.msg-action-btn {563  min-width: 40px;564  min-height: 36px;565  padding: 4px 10px;566  border-radius: 8px;567  color: var(--text-dim);568  font-size: 12px;569  display: inline-flex;570  align-items: center;571  gap: 5px;572}573574.msg-action-btn:hover {575  background: var(--surface-raised);576  color: var(--text);577}578579.branch-nav {580  display: inline-flex;581  align-items: center;582  gap: 2px;583  font-family: var(--font-mono), monospace;584  font-size: 12px;585  color: var(--text-dim);586}587588.branch-nav button {589  min-width: 34px;590  min-height: 36px;591  border-radius: 8px;592  display: inline-flex;593  align-items: center;594  justify-content: center;595}596597.branch-nav button:disabled {598  opacity: 0.3;599  cursor: default;600}601602.branch-nav button:not(:disabled):hover {603  background: var(--surface-raised);604  color: var(--text);605}606607/* Markdown internals */608.msg-body pre {609  background: var(--ink-900);610  border: 1px solid var(--border);611  border-radius: 12px;612  padding: 0;613  overflow: hidden;614  margin: 14px 0;615}616617:root[data-theme="light"] .msg-body pre {618  background: #14181f;619}620621.code-block-header {622  display: flex;623  align-items: center;624  justify-content: space-between;625  padding: 6px 12px;626  border-bottom: 1px solid var(--ink-700);627  font-family: var(--font-mono), monospace;628  font-size: 11px;629  color: #8b96a5;630}631632.code-block-header button {633  color: #8b96a5;634  font-family: inherit;635  font-size: 11px;636  padding: 4px 8px;637  border-radius: 6px;638  min-height: 28px;639}640641.code-block-header button:hover {642  color: #eef2f7;643  background: rgba(255, 255, 255, 0.06);644}645646.msg-body pre code {647  display: block;648  padding: 12px 14px;649  overflow-x: auto;650  font-size: 13.5px;651  line-height: 1.55;652  background: transparent;653}654655.msg-body code:not(pre code) {656  background: var(--surface-raised-2);657  border: 1px solid var(--border);658  padding: 1px 5px;659  border-radius: 5px;660  font-size: 0.86em;661}662663.msg-body table {664  border-collapse: collapse;665  display: block;666  overflow-x: auto;667  max-width: 100%;668  margin: 14px 0;669  font-size: 14.5px;670}671672.msg-body th,673.msg-body td {674  border: 1px solid var(--border);675  padding: 6px 12px;676  text-align: left;677}678679.msg-body th {680  background: var(--surface-raised);681}682683.msg-body blockquote {684  border-left: 3px solid var(--signal-500);685  margin: 14px 0;686  padding: 2px 0 2px 14px;687  color: var(--text-dim);688}689690.msg-body img {691  max-width: 100%;692  border-radius: 10px;693}694695/* ---------- Jump-to-latest pill ---------- */696697.jump-pill {698  position: absolute;699  bottom: 150px;700  left: 50%;701  transform: translateX(-50%);702  z-index: 10;703  background: var(--surface-raised-2);704  border: 1px solid var(--border);705  color: var(--text);706  border-radius: 999px;707  padding: 8px 16px;708  font-size: 13px;709  display: flex;710  align-items: center;711  gap: 6px;712  box-shadow: var(--card-shadow);713}714715/* ---------- Composer + Model Rail ---------- */716717.composer-wrap {718  border-top: 1px solid var(--border);719  background: var(--surface);720  padding: 0 12px calc(10px + env(safe-area-inset-bottom));721}722723.composer {724  max-width: 780px;725  margin: 0 auto;726}727728/* The Model Rail: machined cartridge attached to the composer */729.model-rail {730  display: flex;731  align-items: center;732  gap: 10px;733  width: 100%;734  padding: 8px 12px;735  margin-top: 10px;736  border: 1px solid var(--border);737  border-radius: 12px 12px 0 0;738  border-bottom: none;739  background: var(--surface-raised);740  text-align: left;741  position: relative;742  overflow: hidden;743  transition: border-color 0.2s;744}745746.model-rail:hover {747  border-color: color-mix(in srgb, var(--signal-500) 55%, var(--border));748}749750.model-rail::before {751  /* signal edge: pulses teal while streaming */752  content: "";753  position: absolute;754  left: 0;755  top: 0;756  bottom: 0;757  width: 3px;758  background: var(--border);759  transition: background 0.3s;760}761762.model-rail.live::before {763  background: var(--signal-500);764  animation: pulse 1.2s ease-in-out infinite;765}766767.rail-glyph {768  font-family: var(--font-mono), monospace;769  font-size: 13px;770  font-weight: 600;771  color: var(--signal-500);772  border: 1px solid var(--border);773  border-radius: 7px;774  width: 30px;775  height: 30px;776  display: inline-flex;777  align-items: center;778  justify-content: center;779  flex: none;780  background: var(--surface);781}782783.rail-main {784  flex: 1;785  min-width: 0;786  display: flex;787  flex-direction: column;788  gap: 3px;789}790791.rail-model-id {792  font-family: var(--font-mono), monospace;793  font-size: 12.5px;794  font-weight: 500;795  color: var(--text);796  white-space: nowrap;797  overflow: hidden;798  text-overflow: ellipsis;799}800801.rail-meta {802  display: flex;803  align-items: center;804  gap: 8px;805  font-family: var(--font-mono), monospace;806  font-size: 10.5px;807  color: var(--text-dim);808}809810.ctx-meter {811  flex: 1;812  max-width: 120px;813  height: 3px;814  background: var(--border);815  border-radius: 2px;816  overflow: hidden;817}818819.ctx-meter .fill {820  height: 100%;821  background: var(--amber-500);822  border-radius: 2px;823  transition: width 0.4s;824}825826.price-chip {827  color: var(--amber-500);828  flex: none;829}830831.rail-chevron {832  color: var(--text-dim);833  flex: none;834}835836.composer-box {837  display: flex;838  align-items: flex-end;839  gap: 8px;840  border: 1px solid var(--border);841  border-radius: 0 0 14px 14px;842  background: var(--surface-raised);843  padding: 8px 8px 8px 14px;844  transition: border-color 0.2s;845}846847.composer-box:focus-within {848  border-color: var(--signal-500);849}850851.composer-box textarea {852  flex: 1;853  background: transparent;854  border: none;855  resize: none;856  outline: none;857  font-size: 16px; /* prevents iOS zoom */858  line-height: 1.5;859  max-height: 40dvh;860  padding: 6px 0;861  color: var(--text);862}863864.composer-box textarea::placeholder {865  color: var(--text-dim);866  opacity: 0.7;867}868869.send-btn {870  width: 44px;871  height: 44px;872  border-radius: 11px;873  background: var(--signal-500);874  color: #07110f;875  display: inline-flex;876  align-items: center;877  justify-content: center;878  flex: none;879  transition: background 0.15s, transform 0.1s;880}881882.send-btn:hover {883  background: var(--signal-600);884}885886.send-btn:active {887  transform: scale(0.94);888}889890.send-btn:disabled {891  background: var(--border);892  color: var(--text-dim);893  cursor: default;894}895896.send-btn.stop {897  background: var(--surface-raised-2);898  color: var(--danger);899  border: 1px solid var(--border);900}901902/* ---------- Bottom sheet (model picker) ---------- */903904.sheet-scrim {905  position: fixed;906  inset: 0;907  z-index: 60;908  background: rgba(0, 0, 0, 0.5);909  animation: fadeIn 0.2s;910}911912@keyframes fadeIn {913  from {914    opacity: 0;915  }916}917918.sheet {919  position: fixed;920  z-index: 61;921  left: 0;922  right: 0;923  bottom: 0;924  top: max(24px, env(safe-area-inset-top));925  background: var(--surface-raised);926  border-radius: 18px 18px 0 0;927  box-shadow: var(--sheet-shadow);928  display: flex;929  flex-direction: column;930  animation: sheetUp 0.28s cubic-bezier(0.32, 0.72, 0.18, 1.02);931}932933@keyframes sheetUp {934  from {935    transform: translateY(40px);936    opacity: 0.5;937  }938}939940@media (min-width: 1024px) {941  .sheet {942    left: 50%;943    right: auto;944    top: 50%;945    bottom: auto;946    transform: translate(-50%, -50%);947    width: 660px;948    height: min(78vh, 740px);949    border-radius: 18px;950    animation: fadeIn 0.18s;951  }952}953954.sheet-handle {955  width: 40px;956  height: 4px;957  border-radius: 2px;958  background: var(--border);959  margin: 10px auto 2px;960  flex: none;961}962963@media (min-width: 1024px) {964  .sheet-handle {965    display: none;966  }967}968969.sheet-search {970  position: sticky;971  top: 0;972  padding: 10px 14px;973  display: flex;974  gap: 8px;975  align-items: center;976}977978.sheet-search input {979  flex: 1;980  background: var(--surface);981  border: 1px solid var(--border);982  border-radius: 11px;983  padding: 11px 14px;984  font-size: 16px;985  outline: none;986}987988.sheet-search input:focus {989  border-color: var(--signal-500);990}991992.filter-row {993  display: flex;994  gap: 6px;995  padding: 2px 14px 10px;996  overflow-x: auto;997  flex: none;998  scrollbar-width: none;999}10001001.filter-row::-webkit-scrollbar {1002  display: none;1003}10041005.filter-chip {1006  flex: none;1007  padding: 6px 12px;1008  border-radius: 999px;1009  border: 1px solid var(--border);1010  font-size: 12.5px;1011  color: var(--text-dim);1012  background: var(--surface);1013  min-height: 32px;1014}10151016.filter-chip.on {1017  border-color: var(--signal-500);1018  color: var(--signal-500);1019  background: var(--signal-alpha);1020}10211022.model-list {1023  flex: 1;1024  overflow-y: auto;1025  padding: 0 8px 20px;1026}10271028.model-section-label {1029  font-family: var(--font-mono), monospace;1030  font-size: 10.5px;1031  text-transform: uppercase;1032  letter-spacing: 0.08em;1033  color: var(--text-dim);1034  padding: 14px 10px 6px;1035}10361037.model-row {1038  display: flex;1039  align-items: center;1040  gap: 10px;1041  width: 100%;1042  text-align: left;1043  padding: 10px;1044  border-radius: 10px;1045  min-height: 56px;1046}10471048.model-row:hover,1049.model-row.highlight {1050  background: var(--surface-raised-2);1051}10521053.model-row.selected {1054  background: var(--signal-alpha);1055}10561057.model-row .prov-glyph {1058  font-family: var(--font-mono), monospace;1059  font-size: 11px;1060  font-weight: 600;1061  color: var(--text-dim);1062  border: 1px solid var(--border);1063  border-radius: 7px;1064  width: 30px;1065  height: 30px;1066  display: inline-flex;1067  align-items: center;1068  justify-content: center;1069  flex: none;1070  background: var(--surface);1071}10721073.model-row .m-main {1074  flex: 1;1075  min-width: 0;1076}10771078.model-row .m-name {1079  font-size: 14px;1080  font-weight: 500;1081  color: var(--text);1082  white-space: nowrap;1083  overflow: hidden;1084  text-overflow: ellipsis;1085}10861087.model-row .m-sub {1088  font-family: var(--font-mono), monospace;1089  font-size: 11px;1090  color: var(--text-dim);1091  display: flex;1092  gap: 8px;1093  white-space: nowrap;1094  overflow: hidden;1095}10961097.model-row .fav-btn {1098  width: 40px;1099  height: 40px;1100  border-radius: 9px;1101  color: var(--text-dim);1102  display: inline-flex;1103  align-items: center;1104  justify-content: center;1105  flex: none;1106}11071108.model-row .fav-btn.on {1109  color: var(--amber-500);1110}11111112.model-row .fav-btn:hover {1113  background: var(--surface);1114}11151116.cap-badges {1117  display: flex;1118  gap: 4px;1119  flex: none;1120}11211122.cap-badge {1123  font-family: var(--font-mono), monospace;1124  font-size: 9.5px;1125  color: var(--text-dim);1126  border: 1px solid var(--border);1127  border-radius: 4px;1128  padding: 1px 4px;1129  text-transform: uppercase;1130}11311132/* ---------- Login ---------- */11331134.login-page {1135  min-height: 100dvh;1136  display: flex;1137  align-items: center;1138  justify-content: center;1139  padding: 24px;1140  background:1141    radial-gradient(1200px 500px at 50% -10%, var(--signal-alpha), transparent 60%),1142    var(--surface);1143}11441145.login-card {1146  width: 100%;1147  max-width: 380px;1148  background: var(--surface-raised);1149  border: 1px solid var(--border);1150  border-radius: 18px;1151  padding: 28px;1152  box-shadow: var(--card-shadow);1153}11541155.login-card .wordmark {1156  font-size: 15px;1157  display: block;1158  margin-bottom: 4px;1159}11601161.login-card .sub {1162  color: var(--text-dim);1163  font-size: 13px;1164  margin: 0 0 22px;1165}11661167.login-card label {1168  display: block;1169  font-size: 12.5px;1170  font-weight: 500;1171  color: var(--text-dim);1172  margin: 14px 0 6px;1173}11741175.login-card input {1176  width: 100%;1177  background: var(--surface);1178  border: 1px solid var(--border);1179  border-radius: 10px;1180  padding: 12px 14px;1181  font-size: 16px;1182  outline: none;1183}11841185.login-card input:focus {1186  border-color: var(--signal-500);1187}11881189.login-card .login-btn {1190  width: 100%;1191  margin-top: 22px;1192  background: var(--signal-500);1193  color: #07110f;1194  font-weight: 600;1195  font-size: 15px;1196  border-radius: 11px;1197  padding: 13px;1198  transition: background 0.15s;1199}12001201.login-card .login-btn:hover {1202  background: var(--signal-600);1203}12041205.login-card .login-btn:disabled {1206  opacity: 0.6;1207}12081209.login-error {1210  margin-top: 14px;1211  color: var(--danger);1212  font-size: 13.5px;1213}12141215/* ---------- Settings / usage ---------- */12161217.settings-page {1218  max-width: 780px;1219  margin: 0 auto;1220  padding: 20px 16px calc(40px + env(safe-area-inset-bottom));1221}12221223.settings-page h1 {1224  font-size: 20px;1225  margin: 8px 0 20px;1226}12271228.settings-page h2 {1229  font-size: 14px;1230  font-family: var(--font-mono), monospace;1231  text-transform: uppercase;1232  letter-spacing: 0.07em;1233  color: var(--text-dim);1234  margin: 28px 0 12px;1235  font-weight: 500;1236}12371238.stat-grid {1239  display: grid;1240  grid-template-columns: repeat(2, 1fr);1241  gap: 10px;1242}12431244@media (min-width: 640px) {1245  .stat-grid {1246    grid-template-columns: repeat(4, 1fr);1247  }1248}12491250.stat-tile {1251  background: var(--surface-raised);1252  border: 1px solid var(--border);1253  border-radius: 12px;1254  padding: 14px;1255}12561257.stat-tile .v {1258  font-family: var(--font-mono), monospace;1259  font-size: 20px;1260  font-weight: 600;1261}12621263.stat-tile .v.cost {1264  color: var(--amber-500);1265}12661267.stat-tile .k {1268  font-size: 12px;1269  color: var(--text-dim);1270  margin-top: 2px;1271}12721273.period-tabs {1274  display: flex;1275  gap: 6px;1276  margin-bottom: 14px;1277}12781279.usage-table {1280  width: 100%;1281  border-collapse: collapse;1282  font-size: 13.5px;1283}12841285.usage-table th {1286  text-align: left;1287  font-family: var(--font-mono), monospace;1288  font-size: 10.5px;1289  text-transform: uppercase;1290  letter-spacing: 0.07em;1291  color: var(--text-dim);1292  font-weight: 500;1293  padding: 8px 10px;1294  border-bottom: 1px solid var(--border);1295}12961297.usage-table td {1298  padding: 9px 10px;1299  border-bottom: 1px solid var(--border);1300}13011302.usage-table td.num {1303  font-family: var(--font-mono), monospace;1304  text-align: right;1305}13061307.usage-table th.num {1308  text-align: right;1309}13101311.settings-row {1312  display: flex;1313  align-items: center;1314  justify-content: space-between;1315  gap: 12px;1316  background: var(--surface-raised);1317  border: 1px solid var(--border);1318  border-radius: 12px;1319  padding: 14px;1320  margin-bottom: 10px;1321}13221323.settings-row .r-label {1324  font-size: 14px;1325  font-weight: 500;1326}13271328.settings-row .r-sub {1329  font-size: 12.5px;1330  color: var(--text-dim);1331  margin-top: 2px;1332}13331334.btn {1335  padding: 9px 16px;1336  border-radius: 9px;1337  border: 1px solid var(--border);1338  background: var(--surface);1339  font-size: 13.5px;1340  font-weight: 500;1341  min-height: 40px;1342}13431344.btn:hover {1345  border-color: var(--signal-500);1346}13471348.btn.primary {1349  background: var(--signal-500);1350  border-color: var(--signal-500);1351  color: #07110f;1352}13531354.btn.danger:hover {1355  border-color: var(--danger);1356  color: var(--danger);1357}13581359/* thin scrollbars */1360*::-webkit-scrollbar {1361  width: 8px;1362  height: 8px;1363}13641365*::-webkit-scrollbar-thumb {1366  background: var(--border);1367  border-radius: 4px;1368}13691370*::-webkit-scrollbar-track {1371  background: transparent;1372}1373