/* files.tarassov.ch in the swiss-function look (gitea@code.tarassov.ch:ux/swiss-function, AESTHETICS.md):
   the Login panel's layout, with Input, PasswordInput, Button (sheet key with the keycap dish) and Progress
   restated as plain CSS, since the page has no React and no build step. Tokens are the subset the page uses,
   copied from src/tokens/tokens.css; the dark set applies through prefers-color-scheme here (the library
   switches on a data-theme attribute instead).
   Everything is served from this origin (the CSP allows nothing else): the font from /fonts, the dither
   pattern from /dither.svg in place of the library's data: URI. */

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/jetbrains-mono-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/jetbrains-mono-latin-500-normal.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/jetbrains-mono-latin-700-normal.woff2") format("woff2");
}

/* The face colour of a key (lib/surface): registered so a hover recolour transitions and children keep their own. */
@property --sf-cap {
  syntax: "<color>";
  inherits: false;
  initial-value: transparent;
}

/* --- Tokens (light) ------------------------------------------------------------------------------------------ */
:root {
  --sf-unit: 1.5rem;

  --sf-color-bg: #ffffff;
  --sf-color-bg-subtle: #f9fafb;
  --sf-color-input-bg: #f3f4f6;
  --sf-color-fg: #0a0a0a;
  --sf-color-muted: #6b7280;
  --sf-color-border: #e5e7eb;
  --sf-color-primary: #2563eb;
  --sf-color-primary-fg: #ffffff;
  --sf-color-primary-hover: #1d4ed8;
  --sf-color-danger: #dc2626;
  --sf-color-success: #16a34a;
  --sf-color-focus-ring: #2563eb;
  --sf-focus-ring-width: 2px;

  --sf-radius-default: 0.125rem;

  --sf-font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --sf-font-mono:
    "JetBrains Mono", ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace;
  --sf-font-mono-adjust: 0.52;
  --sf-font-size-sm: 0.875rem;
  --sf-font-size-md: 1rem;
  --sf-font-weight-medium: 500;
  --sf-font-weight-bold: 700;
  --sf-line-height-tight: 1.25;

  /* One light from the top left; every edge, groove and cast below follows it. */
  --sf-light-x: -1;
  --sf-light-y: -1;
  --sf-light-angle: calc(atan2(var(--sf-light-y), var(--sf-light-x)) + 270deg);

  --sf-elevation-1: calc(var(--sf-light-x) * -1px) calc(var(--sf-light-y) * -1px) 1px rgb(0 0 0 / 0.06);
  --sf-elevation-2:
    calc(var(--sf-light-x) * -1px) calc(var(--sf-light-y) * -1px) 2px rgb(0 0 0 / 0.05),
    calc(var(--sf-light-x) * -2px) calc(var(--sf-light-y) * -2px) 4px rgb(0 0 0 / 0.05);

  --sf-edge-lit-color: rgb(255 255 255 / 0.24);
  --sf-edge-shade-color: rgb(0 0 0 / 0.1);
  --sf-edge:
    inset calc(var(--sf-light-x) * -1px) calc(var(--sf-light-y) * -1px) 0 0 var(--sf-edge-lit-color),
    inset calc(var(--sf-light-x) * 1px) calc(var(--sf-light-y) * 1px) 0 0 var(--sf-edge-shade-color);
  --sf-groove:
    inset calc(var(--sf-light-x) * -1.5px) calc(var(--sf-light-y) * -1.5px) 1px 0 rgb(0 0 0 / 0.1),
    inset calc(var(--sf-light-x) * 1px) calc(var(--sf-light-y) * 1px) 2px 0 rgb(255 255 255 / 0.55);
  --sf-curve: 0.045;

  --sf-duration-fast: 120ms;
  --sf-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --sf-ease-snap: cubic-bezier(0.34, 1.7, 0.5, 1);

  color-scheme: light dark;
}

/* --- Tokens (dark) ------------------------------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
  :root {
    --sf-color-bg: #0a0a0a;
    --sf-color-bg-subtle: #171717;
    --sf-color-input-bg: #171717;
    --sf-color-fg: #fafafa;
    --sf-color-muted: #9ca3af;
    --sf-color-border: #262626;
    --sf-color-primary: #3b82f6;
    --sf-color-primary-hover: #60a5fa;
    --sf-color-danger: #ef4444;
    --sf-color-success: #22c55e;
    --sf-color-focus-ring: #60a5fa;

    /* Near-black swallows soft shadows: a hard cast in the border colour, a lit rim and a faint film. */
    --sf-elevation-1:
      inset 0 0 0 1px rgb(255 255 255 / 0.06),
      calc(var(--sf-light-x) * -2px) calc(var(--sf-light-y) * -2px) 0 0 var(--sf-color-border);
    --sf-elevation-2:
      inset 0 0 0 1px rgb(255 255 255 / 0.1), inset 0 0 0 9999px rgb(255 255 255 / 0.03),
      calc(var(--sf-light-x) * -3px) calc(var(--sf-light-y) * -3px) 0 0 var(--sf-color-border);

    --sf-edge-lit-color: rgb(255 255 255 / 0.08);
    --sf-edge-shade-color: rgb(0 0 0 / 0.36);
    --sf-groove:
      inset calc(var(--sf-light-x) * -1.5px) calc(var(--sf-light-y) * -1.5px) 2px 0 rgb(0 0 0 / 0.4),
      inset calc(var(--sf-light-x) * 1px) calc(var(--sf-light-y) * 1px) 1px 0 rgb(255 255 255 / 0.05);
  }
}

/* --- Reset --------------------------------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 12vh 16px var(--sf-unit);
  font-family: var(--sf-font-sans);
  font-size: var(--sf-font-size-md);
  line-height: var(--sf-unit);
  color: var(--sf-color-fg);
  background-color: var(--sf-color-bg-subtle);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
button,
input {
  font: inherit;
  color: inherit;
}
p {
  margin: 0;
}
:focus {
  outline: none;
}
:focus-visible {
  outline: var(--sf-focus-ring-width) solid var(--sf-color-focus-ring);
  outline-offset: 2px;
}
[hidden] {
  display: none !important;
}

/* --- Panel (Login) ------------------------------------------------------------------------------------------- */
.panel {
  inline-size: min(100%, calc(var(--sf-unit) * 18));
  background-color: var(--sf-color-bg);
  border: 1px solid var(--sf-color-border);
  border-radius: var(--sf-radius-default);
  box-shadow: var(--sf-elevation-2);
  font-family: var(--sf-font-mono);
  font-size-adjust: var(--sf-font-mono-adjust);
}
.titlebar {
  display: flex;
  align-items: center;
  gap: calc(var(--sf-unit) / 2);
  block-size: calc(var(--sf-unit) * 1.5);
  padding-inline: calc(var(--sf-unit) / 2);
  border-block-end: 1px solid var(--sf-color-border);
}
.title {
  margin: 0;
  font-size: var(--sf-font-size-sm);
  font-weight: var(--sf-font-weight-medium);
  white-space: nowrap;
}
.dither {
  flex: 1;
  block-size: 6px;
  background-color: color-mix(in srgb, var(--sf-color-muted), transparent 45%);
  -webkit-mask-image: url("/dither.svg");
  mask-image: url("/dither.svg");
  -webkit-mask-size: 4px 4px;
  mask-size: 4px 4px;
}
.body {
  display: grid;
  gap: var(--sf-unit);
  padding: calc(var(--sf-unit) * 1.5);
}
.intro {
  font-size: var(--sf-font-size-sm);
}
.stack {
  display: grid;
  gap: var(--sf-unit);
}
.field {
  display: grid;
  gap: calc(var(--sf-unit) / 4);
}
.label {
  font-size: var(--sf-font-size-sm);
  letter-spacing: 0.02em;
}

/* --- Input + PasswordInput ----------------------------------------------------------------------------------- */
.password {
  display: flex;
  align-items: stretch;
  gap: calc(var(--sf-unit) / 4);
}
.input {
  flex: 1;
  min-inline-size: 0;
  block-size: calc(var(--sf-unit) * 1.5);
  padding-inline: calc(var(--sf-unit) / 2);
  --sf-cap: var(--sf-color-input-bg);
  background-color: var(--sf-cap);
  border: 1px solid var(--sf-color-border);
  border-radius: var(--sf-radius-default);
  font-family: var(--sf-font-mono);
  font-size-adjust: var(--sf-font-mono-adjust);
  line-height: var(--sf-line-height-tight);
  caret-shape: block;
  caret-color: var(--sf-color-primary);
  box-shadow: var(--sf-groove);
  transition:
    background-color var(--sf-duration-fast) var(--sf-ease-out),
    border-color var(--sf-duration-fast) var(--sf-ease-out);
}
.input:focus {
  --sf-cap: var(--sf-color-bg);
  border-color: var(--sf-color-primary);
  outline: none;
}
.input[aria-invalid="true"] {
  border-color: var(--sf-color-danger);
}
.input:disabled {
  opacity: 0.5;
  box-shadow: none;
}
.toggle {
  flex: none;
  border: 0;
  background: none;
  cursor: pointer;
  padding-inline: calc(var(--sf-unit) / 2);
  font-family: var(--sf-font-mono);
  font-size-adjust: var(--sf-font-mono-adjust);
  font-size: var(--sf-font-size-sm);
  border-radius: var(--sf-radius-default);
}
.toggle:focus-visible {
  outline-offset: 1px;
}

/* --- Button (primary sheet key, keycap dish) ----------------------------------------------------------------- */
.button {
  --sf-cap: var(--sf-color-primary);
  --_curve: var(--sf-curve);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 100%;
  block-size: calc(var(--sf-unit) * 1.5);
  padding-inline: calc(var(--sf-unit) * 2 / 3);
  border: 1px solid color-mix(in srgb, var(--sf-color-primary), black 12%);
  border-radius: var(--sf-radius-default);
  color: var(--sf-color-primary-fg);
  font-family: var(--sf-font-mono);
  font-size-adjust: var(--sf-font-mono-adjust);
  font-weight: var(--sf-font-weight-medium);
  line-height: var(--sf-line-height-tight);
  cursor: pointer;
  user-select: none;
  background-color: var(--sf-cap);
  background-image: linear-gradient(
    var(--sf-light-angle),
    oklch(from var(--sf-cap) calc(l - var(--_curve) * 0.42) c h) 0%,
    oklch(from var(--sf-cap) calc(l - var(--_curve) * 0.73) c h) 20%,
    oklch(from var(--sf-cap) calc(l - var(--_curve) * 0.47) c h) 40%,
    oklch(from var(--sf-cap) l c h) 62.5%,
    oklch(from var(--sf-cap) calc(l + var(--_curve) * 0.44) c h) 80%,
    oklch(from var(--sf-cap) calc(l + var(--_curve)) c h) 100%
  );
  box-shadow: var(--sf-edge), var(--sf-elevation-2);
  transition:
    --sf-cap var(--sf-duration-fast) var(--sf-ease-out),
    box-shadow var(--sf-duration-fast) var(--sf-ease-out),
    transform var(--sf-duration-fast) var(--sf-ease-snap);
}
.button:hover:not(:disabled) {
  --sf-cap: var(--sf-color-primary-hover);
}
/* Pressed is travel: one elevation step down and 1px, never an inverted dent. */
.button:active:not(:disabled) {
  box-shadow: var(--sf-edge), var(--sf-elevation-1);
  transform: translateY(1px);
}
.button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  box-shadow: none;
}

/* --- The unlocked file --------------------------------------------------------------------------------------- */
.file {
  display: grid;
  gap: var(--sf-unit);
}
.filename {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 calc(var(--sf-unit) / 2);
}
.filename strong {
  font-weight: var(--sf-font-weight-bold);
  word-break: break-all;
}
.muted {
  color: var(--sf-color-muted);
  font-size: var(--sf-font-size-sm);
}

/* --- Progress (track + indicator) ---------------------------------------------------------------------------- */
.progress {
  position: relative;
  overflow: hidden;
  block-size: calc(var(--sf-unit) / 3);
  background-color: var(--sf-color-input-bg);
  border-radius: var(--sf-radius-default);
  box-shadow: var(--sf-groove);
}
.indicator {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  inline-size: var(--progress, 0%);
  background-color: var(--sf-color-primary);
  border-radius: inherit;
}
.progress[data-done] .indicator {
  background-color: var(--sf-color-success);
}

/* --- Status and the terminal error line ---------------------------------------------------------------------- */
.status {
  font-size: var(--sf-font-size-sm);
}
.status:empty {
  display: none;
}
.status.error {
  display: flex;
  gap: calc(var(--sf-unit) / 2);
  align-items: baseline;
  padding: calc(var(--sf-unit) / 2);
  color: var(--sf-color-danger);
  background-color: color-mix(in srgb, var(--sf-color-danger), transparent 90%);
  border: 1px solid color-mix(in srgb, var(--sf-color-danger), transparent 68%);
  border-radius: var(--sf-radius-default);
}
.status.error::before {
  content: "!" / "";
  font-weight: var(--sf-font-weight-bold);
}

/* --- Footer -------------------------------------------------------------------------------------------------- */
.footer {
  inline-size: min(100%, calc(var(--sf-unit) * 18));
  margin-block-start: var(--sf-unit);
  font-size: var(--sf-font-size-sm);
  color: var(--sf-color-muted);
}
.footer a {
  color: inherit;
  text-decoration-color: var(--sf-color-border);
  text-underline-offset: 3px;
}
.footer a:hover {
  color: var(--sf-color-primary);
  text-decoration-color: currentColor;
}

@media (prefers-reduced-motion: reduce) {
  .input,
  .button {
    transition: none;
  }
}
