/* Ralotech Rental Services — tokens and glass primitives.
 *
 * The RALOTECH glass model (docs/ralotech-reference.css, design-system README) in the
 * handoff palette: dark charcoal, warm ivory ink, warm greys, muted metallic gold, and
 * warm gold/amber/bronze light pools under the glass. One file, no build step.
 * Owned by the architect. Builders link it first and add their own stylesheet after it.
 * Class names keep the rt- prefix so the reference file reads across unchanged.
 *
 * CONTRAST (WCAG 2.x relative luminance, computed 2026-10-27, scratch script contrast.mjs).
 * The pools sit at opacity 0.42. The "lightest point" is the worst case: a pool's centre
 * colour at full opacity 0.42 over --bg, with the glass film (white at 0.055) on top; blur
 * only makes the real peak darker than this. Columns: plain --bg · gold pool+glass
 * (#4e4025, the brightest of the three) · amber pool+glass (#50371f) · bronze pool+glass
 * (#443324). Every text token clears 4.5:1 in every column.
 *
 *   --ink   #f3ede3   16.06 · 8.65 · 9.45 · 10.34
 *   --soft  #d6ccbb   11.76 · 6.34 · 6.93 ·  7.57
 *   --dim   #baafa0    8.66 · 4.67 · 5.10 ·  5.58   (the tightest: 4.67)
 *   --gold  #ddbf78   10.50 · 5.66 · 6.19 ·  6.76
 *   --ok    #9ad594   10.97 · 5.91 · 6.46 ·  7.06
 *   --bad   #ffa591    9.83 · 5.30 · 5.79 ·  6.33
 *   --deep  #14120f on --ink button 16.06 · on --gold button 10.50
 *   glass over plain --bg is #211f1c: ink 14.12 · soft 10.34 · dim 7.61
 *
 * The README's trap still applies: these are computed, not photographed. Before delivery,
 * measure the built page by the lightest-pixel method and report 0 AA failures.
 */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/inter-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Syne";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("/fonts/syne-latin.woff2") format("woff2");
}

:root {
  /* ---- ink */
  --ink: #f3ede3;   /* headings and body: warm ivory */
  --soft: #d6ccbb;  /* leads, supporting text */
  --dim: #baafa0;   /* notes, captions, footer */
  --bg: #14120f;    /* dark charcoal, the ground of everything */
  --deep: #14120f;  /* text on a light button */
  --gold: #ddbf78;  /* muted metallic gold: emphasis, focus, links */
  --ok: #9ad594;    /* confirmed, live */
  --bad: #ffa591;   /* error, declined */

  /* ---- type */
  --sans: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --display: Syne, Inter, sans-serif; /* the wordmark only */

  /* ---- the glass: the single surface of the system */
  --glass: rgba(255, 255, 255, 0.055);
  --glass-line: rgba(255, 255, 255, 0.14);
  --blur: saturate(160%) blur(26px);

  /* ---- the light under the glass */
  --pool-gold: #866524;
  --pool-amber: #8a4e17;
  --pool-bronze: #6b4322;
  --pool-opacity: 0.42;

  /* ---- measure */
  --r: 28px;      /* panel */
  --r-bar: 22px;  /* bar, menu */
  --r-in: 20px;   /* inside a panel, textarea */
  --gut: 22px;    /* side gutter; 18px under 760px */
  --max: 1120px;  /* column width */
  --tap: 44px;    /* minimum hit target */
  --btn: 52px;    /* capsule button and field height */

  /* ---- motion: one curve for everything */
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
  --t: 0.25s;
}

@media (max-width: 759px) {
  :root { --gut: 18px; --r: 24px; }
}

/* ---- base */
html { background: var(--bg); color-scheme: dark; -webkit-text-size-adjust: 100%; }
body { margin: 0; background: var(--bg); color: var(--ink); font: 400 17px/1.55 var(--sans); letter-spacing: -0.011em; -webkit-font-smoothing: antialiased; }
*, *::before, *::after { box-sizing: border-box; }
/* the hidden attribute must win over component display rules (WhatsApp CTAs stay hidden until a number is set) */
[hidden] { display: none !important; }

/* ---- the light behind. Three slow pools, fixed, so the glass has something to refract.
   Markup: <div class="rt-light" aria-hidden="true"><i class="a"></i><i class="b"></i><i class="c"></i></div>
           <div class="rt-veil" aria-hidden="true"></div>
   Page content sits in a wrapper with position: relative; z-index: 2. */
.rt-light { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.rt-light i { position: absolute; display: block; border-radius: 50%; filter: blur(110px); opacity: var(--pool-opacity); will-change: transform; }
.rt-light .a { width: 68vw; height: 68vw; left: -16vw; top: -18vw; background: radial-gradient(circle, var(--pool-gold) 0%, rgba(134, 101, 36, 0) 70%); animation: rt-a 34s ease-in-out infinite alternate; }
.rt-light .b { width: 56vw; height: 56vw; right: -12vw; top: 26vh; background: radial-gradient(circle, var(--pool-amber) 0%, rgba(138, 78, 23, 0) 70%); animation: rt-b 46s ease-in-out infinite alternate; }
.rt-light .c { width: 60vw; height: 60vw; left: 16vw; bottom: -26vw; background: radial-gradient(circle, var(--pool-bronze) 0%, rgba(107, 67, 34, 0) 70%); animation: rt-c 40s ease-in-out infinite alternate; }
@keyframes rt-a { to { transform: translate3d(8vw, 10vh, 0) scale(1.14); } }
@keyframes rt-b { to { transform: translate3d(-10vw, -8vh, 0) scale(1.1); } }
@keyframes rt-c { to { transform: translate3d(6vw, -12vh, 0) scale(1.18); } }
/* the veil pulls the edges back to charcoal so text never competes with the light */
.rt-veil { position: fixed; inset: 0; z-index: 1; pointer-events: none;
  background: radial-gradient(ellipse at 50% 0%, rgba(20, 18, 15, 0) 28%, rgba(20, 18, 15, 0.78) 76%, #14120f 100%); }

/* ---- the glass */
.rt-glass {
  background: var(--glass);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  border-radius: var(--r);
  box-shadow: inset 0 1px 0 var(--glass-line), inset 0 0 0 1px rgba(255, 255, 255, 0.055), 0 24px 60px rgba(0, 0, 0, 0.4);
}
/* where the browser cannot blur, the glass becomes a solid panel instead of a grey smear */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .rt-glass { background: rgba(30, 27, 23, 0.94); }
}

/* ---- type. Big, tight headings are where the expensive look comes from. */
.rt-h1 { font: 600 clamp(44px, 8.4vw, 100px) / 1.03 var(--sans); letter-spacing: -0.045em; color: var(--ink); margin: 0; }
.rt-h2 { font: 600 clamp(33px, 5.2vw, 66px) / 1.03 var(--sans); letter-spacing: -0.045em; color: var(--ink); margin: 0; }
.rt-h3 { font: 550 20px/1.3 var(--sans); letter-spacing: -0.02em; color: var(--ink); margin: 0; }
.rt-body { font: 400 17px/1.55 var(--sans); letter-spacing: -0.011em; color: var(--ink); }
.rt-lead { font: 400 clamp(18px, 2vw, 23px) / 1.5 var(--sans); letter-spacing: -0.014em; color: var(--soft); }
.rt-note { font: 400 16px/1.6 var(--sans); color: var(--dim); }
.rt-gold { color: var(--gold); }
a { color: var(--gold); text-underline-offset: 3px; }

/* the wordmark: "Ralotech Rental Services" in ink, "by Ralotech" dimmed. Syne, weight 500. */
.rt-mark { display: inline-flex; align-items: center; gap: 0.4em; min-height: var(--tap); text-decoration: none;
  font: 500 18px/1 var(--display); letter-spacing: -0.04em; color: var(--dim); }
.rt-mark b { font-weight: inherit; color: var(--ink); }

/* ---- section rhythm: one idea per screen */
.rt-section { padding: clamp(96px, 15vh, 190px) var(--gut); }
.rt-col { max-width: var(--max); margin: 0 auto; }

/* ---- buttons: capsule, 52px, the usual curve */
.rt-btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: var(--btn); padding: 0 28px;
  border: 0; border-radius: 999px; font: 550 16px/1 var(--sans); letter-spacing: -0.012em; text-decoration: none;
  cursor: pointer; transition: transform var(--t) var(--ease), background var(--t); }
.rt-btn-solid { background: var(--ink); color: var(--deep); }
.rt-btn-solid:hover { background: #fff; transform: translateY(-1px); }
.rt-btn-gold { background: var(--gold); color: var(--deep); }
.rt-btn-gold:hover { background: #e8cc8a; transform: translateY(-1px); }
.rt-btn-ghost { color: var(--ink); box-shadow: inset 0 0 0 1px var(--glass-line); background: transparent; }
.rt-btn-ghost:hover { transform: translateY(-1px); background: var(--glass); }
.rt-btn:disabled, .rt-btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; transform: none; }

/* ---- anything you touch is 44px; padding on an inline element does NOT count */
.rt-tap { display: inline-flex; align-items: center; min-height: var(--tap); }

/* ---- focus: visible, always, the same everywhere */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--gold); outline-offset: 3px; border-radius: 10px;
}
.rt-input:focus-visible, .rt-btn:focus-visible { border-radius: 999px; }
textarea.rt-input:focus-visible { border-radius: var(--r-in); }

/* ---- forms.
   Markup: <div class="rt-field"><label class="rt-label" for="x">Name</label>
             <input class="rt-input" id="x" name="x" aria-describedby="x-err">
             <p class="rt-error" id="x-err" hidden></p></div>
   Error: add .is-error to .rt-field AND aria-invalid="true" to the control, unhide .rt-error. */
.rt-field { display: flex; flex-direction: column; gap: 8px; margin: 0 0 18px; }
.rt-label { font: 500 15px/1.3 var(--sans); color: var(--soft); }
.rt-hint { font: 400 14px/1.5 var(--sans); color: var(--dim); margin: 0; }
.rt-input {
  width: 100%; min-height: var(--btn); padding: 0 22px; margin: 0;
  background: var(--glass); color: var(--ink); border: 1px solid var(--glass-line); border-radius: 999px;
  font: 400 17px/1.3 var(--sans); letter-spacing: -0.011em; -webkit-appearance: none; appearance: none;
  transition: border-color var(--t), background var(--t);
}
.rt-input::placeholder { color: var(--dim); opacity: 1; }
.rt-input:hover { border-color: rgba(255, 255, 255, 0.22); }
.rt-input:focus { border-color: var(--gold); outline: none; }
.rt-input:disabled { opacity: 0.5; cursor: not-allowed; }
/* date and time inputs render their own icon; keep it ivory on WebKit */
.rt-input::-webkit-calendar-picker-indicator { filter: invert(0.9) sepia(0.3); cursor: pointer; }
/* select: the same capsule, with a chevron drawn in CSS (no image, so no img-src needed) */
.rt-select { position: relative; }
.rt-select .rt-input { padding-right: 52px; cursor: pointer; }
.rt-select::after { content: ""; position: absolute; right: 24px; top: 50%; width: 9px; height: 9px; pointer-events: none;
  border-right: 2px solid var(--soft); border-bottom: 2px solid var(--soft); transform: translateY(-70%) rotate(45deg); }
.rt-select .rt-input option { background: #1e1b17; color: var(--ink); }
textarea.rt-input { min-height: 140px; padding: 16px 22px; border-radius: var(--r-in); line-height: 1.5; resize: vertical; }
/* checkbox: 24px box inside a 44px row, tick drawn in CSS */
.rt-check { display: flex; align-items: flex-start; gap: 14px; min-height: var(--tap); padding: 10px 0; cursor: pointer;
  font: 400 16px/1.5 var(--sans); color: var(--soft); }
.rt-check input { flex: none; width: 24px; height: 24px; margin: 0; -webkit-appearance: none; appearance: none; cursor: pointer;
  background: var(--glass); border: 1px solid var(--glass-line); border-radius: 8px; position: relative; transition: background var(--t), border-color var(--t); }
.rt-check input::after { content: ""; position: absolute; left: 8px; top: 3px; width: 6px; height: 12px;
  border-right: 2.5px solid var(--deep); border-bottom: 2.5px solid var(--deep); transform: rotate(45deg); opacity: 0; }
.rt-check input:checked { background: var(--gold); border-color: var(--gold); }
.rt-check input:checked::after { opacity: 1; }
.rt-check input:focus-visible { border-radius: 8px; }
/* error state */
.rt-error { margin: 0; font: 400 14px/1.5 var(--sans); color: var(--bad); }
.rt-error[hidden] { display: none; }
.rt-field.is-error .rt-input, .rt-input[aria-invalid="true"] { border-color: var(--bad); }
.rt-field.is-error .rt-check input, .rt-check input[aria-invalid="true"] { border-color: var(--bad); }
.rt-field.is-error .rt-label { color: var(--bad); }
/* form-level message (success or failure after submit), lives on the glass */
.rt-status { padding: 16px 22px; border-radius: var(--r-in); background: var(--glass); border: 1px solid var(--glass-line); color: var(--ink); }
.rt-status.is-error { border-color: var(--bad); }
.rt-status.is-ok { border-color: var(--ok); }

/* ---- status dots for the admin: colour never carries the meaning alone, always paired with the word */
.rt-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--dim); margin-right: 8px; vertical-align: middle; }
.rt-dot.is-ok { background: var(--ok); }
.rt-dot.is-bad { background: var(--bad); }
.rt-dot.is-gold { background: var(--gold); }

/* ---- arrival. Everything enters the same way, slowly, and only when JavaScript is on:
   public/js/rise.js (an external file, loaded in <head> without defer) adds .js to <html>.
   Without it everything is visible. */
.js .rt-rise { opacity: 0; transform: translateY(22px); transition: opacity 0.9s var(--ease), transform 0.9s var(--ease); }
.js .rt-rise.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .rt-light .a, .rt-light .b, .rt-light .c { animation: none; }
  .js .rt-rise { opacity: 1; transform: none; transition: none; }
  .rt-btn, .rt-input, .rt-check input { transition: none; }
  .rt-btn:hover { transform: none; }
}
