/* ==========================================================================
   openmessage.no — design system
   Same look as opentimer.no and orgnummer.no: light neutral background,
   white borderless surfaces, pills, near monochrome. Geist for everything,
   including the big message. Message colors live in --sign-bg/--sign-text.
   ========================================================================== */

@font-face {
  font-family: "Geist";
  src: url("fonts/Geist-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+20AC, U+2122, U+2212, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Geist";
  src: url("fonts/Geist-var-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+1E00-1EFF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Geist Mono";
  src: url("fonts/GeistMono-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+20AC, U+2122, U+2212, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Geist Mono";
  src: url("fonts/GeistMono-var-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+1E00-1EFF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --bg: #f4f4f2;
  --surface: #ffffff;
  --surface-2: #f4f4f2;
  --surface-3: #e9e9e6;
  --text: #171717;
  --text-2: #666666;
  --text-3: #6f6f6f;
  --border: rgba(0, 0, 0, 0.05);
  --border-strong: rgba(0, 0, 0, 0.1);

  --inverse-bg: #171717;
  --inverse-text: #fafafa;

  /* Message colors. The default follows the theme (dark text on a light
     surface); app.js overrides these when a preset is chosen */
  --sign-bg: var(--bg);
  --sign-text: var(--text);

  --shadow-overlay: 0 4px 12px rgba(0, 0, 0, 0.04), 0 24px 60px rgba(0, 0, 0, 0.1);

  --font-sans: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --chevron: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236f6f6f' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");

  color-scheme: light;
}

:root[data-theme="dark"] {
  --bg: #0e0e0e;
  --surface: #191919;
  --surface-2: #0e0e0e;
  --surface-3: #262626;
  --text: #ededed;
  --text-2: #a3a3a3;
  --text-3: #9a9a9a;
  --border: rgba(255, 255, 255, 0.07);
  --border-strong: rgba(255, 255, 255, 0.14);

  --inverse-bg: #fafafa;
  --inverse-text: #171717;

  --shadow-overlay: 0 4px 12px rgba(0, 0, 0, 0.4), 0 24px 60px rgba(0, 0, 0, 0.55);

  --chevron: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239a9a9a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");

  color-scheme: dark;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0e0e0e;
    --surface: #191919;
    --surface-2: #0e0e0e;
    --surface-3: #262626;
    --text: #ededed;
    --text-2: #a3a3a3;
    --text-3: #9a9a9a;
    --border: rgba(255, 255, 255, 0.07);
    --border-strong: rgba(255, 255, 255, 0.14);

    --inverse-bg: #fafafa;
    --inverse-text: #171717;

    --shadow-overlay: 0 4px 12px rgba(0, 0, 0, 0.4), 0 24px 60px rgba(0, 0, 0, 0.55);

    --chevron: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239a9a9a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");

    color-scheme: dark;
  }
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.5;
  color: var(--text);
  background-color: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow-x: hidden;
  transition: background-color 0.25s ease, color 0.25s ease;
}

body.show { overflow: hidden; }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.icon {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex-shrink: 0;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 2px;
  border-radius: 6px;
}

::selection { background: var(--surface-3); }

/* UI chrome should not be text-selectable (iOS long-press and the like) */
button, .site-header, .site-footer, .menu, .toast {
  -webkit-user-select: none;
  user-select: none;
}

@media (prefers-reduced-motion: reduce) {
  /* The banner is exempt: scrolling is the feature itself, not decoration */
  *:not(.banner-track), *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.site-header { background: transparent; }

.header-inner {
  max-width: 980px;
  margin: 0 auto;
  padding: 0 20px;
  height: 68px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.brand {
  font-weight: 600;
  font-size: 15px;
  letter-spacing: -0.01em;
  text-decoration: none;
}

.brand-tld { color: var(--text-3); font-weight: 500; }

.header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.icon-btn {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text);
  background: var(--surface);
  transition: background-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}

.icon-btn:hover { background: var(--surface-3); }
.icon-btn:active { transform: scale(0.94); }

.icon-btn.open { background: var(--inverse-bg); color: var(--inverse-text); }

.pill-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 44px;
  padding: 0 22px;
  border-radius: 999px;
  font-size: 14.5px;
  font-weight: 600;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease,
              transform 0.15s ease, opacity 0.15s ease;
}

.pill-btn:active { transform: scale(0.97); }

.pill-btn.primary { background: var(--inverse-bg); color: var(--inverse-text); }
.pill-btn.primary:hover { opacity: 0.85; }

.pill-btn[disabled] { opacity: 0.4; pointer-events: none; }

/* --------------------------------------------------------------------------
   Settings
   -------------------------------------------------------------------------- */

.settings-wrap { position: relative; }

.menu {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  width: 296px;
  /* Full height: the menu should never scroll on a normal screen – the cap
     is only a safety net for very short windows */
  max-height: calc(100dvh - 90px);
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 20px;
  box-shadow: var(--shadow-overlay);
  padding: 20px;
  z-index: 60;
  transform-origin: top right;
  animation: menu-in 0.16s cubic-bezier(0.2, 0.9, 0.3, 1);
}

@keyframes menu-in {
  from { opacity: 0; transform: scale(0.96) translateY(-4px); }
  to { opacity: 1; transform: scale(1) translateY(0); }
}

.menu-label {
  display: block;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-3);
  margin-bottom: 10px;
}

/* Options share the row evenly when they fit; locales with long words
   («Pantalla completa», «Бегущая строка») wrap to their own row rather
   than wrapping inside the button. gap applies both ways, so the spacing
   between wrapped rows equals the spacing within a row */
.menu-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.menu-grid .opt-btn { flex: 1 1 auto; white-space: nowrap; }

.menu-select {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  font: inherit;
  font-size: 14px;
  color: var(--text);
  background-color: var(--surface-2);
  background-image: var(--chevron);
  background-repeat: no-repeat;
  background-position: right 16px center;
  background-size: 15px;
  border: none;
  border-radius: 12px;
  padding: 11px 44px 11px 14px;
  cursor: pointer;
}

.opt-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 9px 8px;
  border: none;
  border-radius: 999px;
  background: var(--surface-2);
  font-size: 13.5px;
  font-weight: 500;
  text-align: center;
  color: var(--text-2);
  transition: background-color 0.13s ease, color 0.13s ease, transform 0.13s ease;
}

.opt-btn .icon { width: 14px; height: 14px; }

.opt-btn:hover { background: var(--surface-3); color: var(--text); }
.opt-btn:active { transform: scale(0.97); }

.opt-btn.active {
  background: var(--inverse-bg);
  color: var(--inverse-text);
  font-weight: 600;
}

.menu-divider {
  height: 1px;
  background: var(--border);
  margin: 18px -20px;
}

.menu-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  font-size: 14px;
  line-height: 1.35;
  cursor: pointer;
  user-select: none;
}

.switch {
  appearance: none;
  -webkit-appearance: none;
  flex-shrink: 0;
  width: 40px;
  height: 23px;
  border-radius: 999px;
  background: var(--surface-3);
  position: relative;
  cursor: pointer;
  transition: background-color 0.18s ease;
  margin: 0;
}

.switch::after {
  content: "";
  position: absolute;
  top: 2.5px;
  left: 2.5px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
  transition: transform 0.18s ease;
}

.switch:checked { background: var(--inverse-bg); }
.switch:checked::after { transform: translateX(17px); background: var(--inverse-text); }

.menu-info {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 10.5px;
  line-height: 1.7;
  color: var(--text-3);
}

.menu-year { margin-top: 6px; }

.menu-info a { color: var(--text-2); text-decoration: none; }
.menu-info a:hover { text-decoration: underline; }

/* Shortcuts: description on the left, keycaps on the right – Slack style */
.sc-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.sc-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
  color: var(--text-2);
}

.sc-keys {
  display: inline-flex;
  gap: 4px;
  flex-shrink: 0;
}

.kbd {
  font-family: var(--font-mono);
  font-size: 10.5px;
  line-height: 1;
  color: var(--text-2);
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-bottom-width: 2px; /* thicker bottom edge = key feel */
  border-radius: 6px;
  padding: 4px 7px 3px;
  min-width: 24px;
  text-align: center;
  cursor: pointer;
  transition: background-color 0.13s ease, color 0.13s ease, transform 0.08s ease;
}

/* Only keys that actually do something (the buttons) react to hover/click */
kbd.kbd { display: inline-block; cursor: default; }
button.kbd:hover { background: var(--surface-3); color: var(--text); }
button.kbd:active { transform: translateY(1px); }

/* Pure touch screens have no keyboard – the list is just noise there */
@media (hover: none) and (pointer: coarse) {
  .shortcuts-wrap { display: none; }
}

/* --------------------------------------------------------------------------
   The stage: message and controls
   -------------------------------------------------------------------------- */

.container {
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  padding: 0 20px;
  flex: 1;
}

.stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding-bottom: 12px;
}

/* The card is a live preview: it takes the message colors. With the default
   colors it blends into the page background – the stage stays clean */
.message-card {
  width: 100%;
  background: var(--sign-bg);
  color: var(--sign-text);
  border-radius: 28px;
  padding: clamp(28px, 6vw, 60px) clamp(20px, 5vw, 52px);
  transition: background-color 0.25s ease, color 0.25s ease;
}

.message-input {
  display: block;
  width: 100%;
  font: inherit;
  font-size: clamp(1.9rem, 6vw, 4.4rem);
  font-weight: 650;
  line-height: 1.15;
  letter-spacing: -0.03em;
  text-align: center;
  color: inherit;
  caret-color: currentColor;
  background: none;
  border: none;
  outline: none;
  resize: none;
  overflow: hidden;
  padding: 0;
  margin: 0;
}

.message-input::placeholder {
  color: inherit;
  /* 0.48 keeps the placeholder airy AND above the WCAG 3:1 requirement for
     large text, in both light and dark mode */
  opacity: 0.48;
  transition: opacity 0.15s ease;
}

/* The caret should not sit in the middle of the placeholder: it yields on focus */
.message-input:focus::placeholder { opacity: 0; }

.controls {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 24px;
}

/* Stable width when the label changes language */
.show-btn { min-width: 170px; }

/* --------------------------------------------------------------------------
   Color picker – the Finder label colors, as a row of dots in the menu
   -------------------------------------------------------------------------- */

.swatches {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 2px 1px;
}

.swatch {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--sw-bg);
  transition: transform 0.13s ease, box-shadow 0.13s ease;
}

.swatch:hover { transform: scale(1.15); }
.swatch:active { transform: scale(0.95); }

.swatch.active { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--text); }

/* Default: an empty circle, like "no label" in Finder – follows the theme */
.swatch-auto {
  background: transparent;
  border: 1.5px solid var(--text-3);
}

/* --------------------------------------------------------------------------
   Sharing: its own header button with a QR code and link button in a dropdown
   -------------------------------------------------------------------------- */

.share-wrap { position: relative; }

/* The share menu hugs the QR code: 168px content plus the menu padding */
.share-menu { width: 208px; }

.qr-wrap {
  display: flex;
  justify-content: center;
  margin-bottom: 12px;
}

/* Short explanation of what sharing does */
.share-info { margin: 0 0 14px; }

/* Drawn at full resolution and scaled down – pixelated keeps the modules
   crisp. Always dark-on-white, also in dark mode: that scans best */
.qr-wrap canvas {
  width: 100%;
  height: auto;
  border-radius: 12px;
  border: 1px solid var(--border);
  image-rendering: pixelated;
}

.share-btn {
  display: flex;
  width: 100%;
}

/* --------------------------------------------------------------------------
   The display
   -------------------------------------------------------------------------- */

.display {
  position: fixed;
  inset: 0;
  z-index: 80;
  background: var(--sign-bg);
  color: var(--sign-text);
  /* Soft in and out: the surface fades, the content lifts imperceptibly */
  opacity: 0;
  transition: opacity 0.3s ease;
}

.display.visible { opacity: 1; }

/* While fading out the surface must not capture clicks */
.display:not(.visible) { pointer-events: none; }

.display .fit-box,
.display .banner-wrap {
  transform: scale(0.985);
  transition: transform 0.3s ease;
}

.display.visible .fit-box,
.display.visible .banner-wrap { transform: none; }

/* Fill mode: app.js fits the text in as large as possible */
.fit-box {
  position: absolute;
  inset: 0;
  padding: calc(4vmin + env(safe-area-inset-top)) calc(4vmin + env(safe-area-inset-right))
           calc(4vmin + env(safe-area-inset-bottom)) calc(4vmin + env(safe-area-inset-left));
  display: flex;
  align-items: center;
  justify-content: center;
}

.display-text {
  width: 100%;
  max-height: 100%;
  font-weight: 650;
  line-height: 1.12;
  letter-spacing: -0.03em;
  text-align: center;
  /* No automatic line wrapping: the text fills the width on one line and
     only breaks where the user typed a line break */
  white-space: pre;
  overflow: hidden;
}

/* Banner: a single line scrolling continuously from right to left */
.banner-wrap {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  overflow: hidden;
}

.banner-track {
  display: flex;
  white-space: nowrap;
  font-size: 42vh;
  font-weight: 650;
  line-height: 1.15;
  letter-spacing: -0.02em;
  will-change: transform;
  animation: banner-scroll var(--banner-dur, 20s) linear infinite;
}

.banner-item {
  flex-shrink: 0;
  padding-right: var(--banner-gap, 28vw);
}

@keyframes banner-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(calc(-1 * var(--banner-shift, 100vw))); }
}

/* The close button floats top right and retreats when everything is still –
   same behavior as the controls in opentimer's fullscreen */
.display-close {
  position: fixed;
  top: calc(14px + env(safe-area-inset-top));
  right: calc(14px + env(safe-area-inset-right));
  z-index: 85;
  background: color-mix(in srgb, var(--sign-text) 10%, transparent);
  color: var(--sign-text);
  transition: opacity 0.3s ease, background-color 0.15s ease, transform 0.15s ease;
}

.display-close:hover { background: color-mix(in srgb, var(--sign-text) 18%, transparent); }

/* The button never retreats while it has keyboard focus */
body.show.idle .display-close:not(:focus-visible) { opacity: 0; pointer-events: none; }
body.show.idle { cursor: none; }

/* --------------------------------------------------------------------------
   Toast
   -------------------------------------------------------------------------- */

.toast {
  position: fixed;
  inset: auto;
  margin: 0;
  border: 0;
  bottom: calc(24px + env(safe-area-inset-bottom));
  left: 50%;
  transform: translate(-50%, 16px);
  background: var(--inverse-bg);
  color: var(--inverse-text);
  font-size: 14px;
  font-weight: 500;
  padding: 12px 22px;
  border-radius: 999px;
  box-shadow: var(--shadow-overlay);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.22s ease, transform 0.22s ease;
  z-index: 100;
  max-width: calc(100vw - 40px);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.toast.show { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.site-footer {
  text-align: center;
  padding: 24px 20px calc(24px + env(safe-area-inset-bottom));
  font-family: var(--font-mono);
  font-size: 10.5px;
  line-height: 1.9;
  letter-spacing: 0.02em;
  color: var(--text-3);
}

.site-footer p { margin: 0; }
.site-footer a { color: var(--text-2); text-decoration: none; }
.site-footer a:hover { text-decoration: underline; }

/* --------------------------------------------------------------------------
   Mobile
   -------------------------------------------------------------------------- */

@media (max-width: 600px) {
  .controls { margin-top: 20px; gap: 8px; }

  .message-card { border-radius: 22px; }

  .menu { width: min(296px, calc(100vw - 32px)); }
  .share-menu { width: 208px; }
}

@media (max-width: 380px) {
  .show-btn { min-width: 0; }
  .pill-btn { padding: 0 18px; }
}
