/*
 * Proprietary & Confidential
 * Copyright © 2026 Connor Herron. All Rights Reserved.
 * Unauthorized distribution or public hosting prohibited.
 */
/* ============================================================================
   OMMA 3D LAYER — presentation
   ----------------------------------------------------------------------------
   Everything here is additive: without js/omma-3d.js none of these classes are
   ever applied, so the page renders exactly as it did before. Nothing in this
   file changes type, colour or spacing of any existing content — it only places
   canvases behind copy and adds cursor-tracked light.

   BRIGHT / CORPORATE / FINTECH: no dark overlays, no heavy blur, alpha stays
   low enough that every surface reads as ivory glass rather than as a picture.

   NOTHING FLOATS FREE. Rules for a hero orbit, a booking lattice and a fixed
   page-wide mote field used to live here and were cut — ambient decoration
   drifting over the page reads as noise, and the motes came out as dark fuzz on
   a real display. Every canvas that remains is clipped inside a card or a
   bounded stage.
   ========================================================================== */

/* ---------- shared canvas behaviour ---------- */
.omma-card-gl,
.omma-stage-gl {
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* ---------- 1. CARD + FORM SURFACES ---------------------------------------
   The canvas is the card's own live surface; the glare is a cursor-tracked
   highlight on top of it. Both sit under the copy, which is lifted to z-index 2
   so nothing here can ever cover text or intercept a click.                 */
.omma-card { position: relative; }
.omma-card > .omma-card-gl,
.omma-card > .omma-card-glare {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 0;
}
.omma-card > .omma-card-gl {
  opacity: 0;
  transition: opacity .5s var(--ease-out, cubic-bezier(.16,1,.3,1));
}
.omma-card.in > .omma-card-gl,
.omma-card:not(.reveal) > .omma-card-gl { opacity: 1; }

.omma-card > .omma-card-glare {
  background: radial-gradient(340px circle at var(--ogx, 50%) var(--ogy, 0%),
              rgba(226, 180, 92, .16), rgba(226, 180, 92, .05) 42%, transparent 68%);
  opacity: 0;
  transition: opacity .35s ease;
  mix-blend-mode: multiply;
}
.omma-card:hover > .omma-card-glare,
.omma-card:focus-within > .omma-card-glare { opacity: 1; }
/* the one deliberately dark card wants light added, not multiplied out */
.omma-card.wide-classics > .omma-card-glare {
  mix-blend-mode: screen;
  background: radial-gradient(340px circle at var(--ogx, 50%) var(--ogy, 0%),
              rgba(240, 220, 166, .20), rgba(240, 220, 166, .06) 42%, transparent 68%);
}

/* every direct child that carries content rides above the surface */
.omma-card > *:not(.omma-card-gl):not(.omma-card-glare) { position: relative; z-index: 2; }

/* ---------- 2. SECTION STAGES (studio / fit check / tools) ----------------- */
.omma-stage {
  position: relative;
  width: 100%;
  overflow: hidden;
  border-radius: 14px;
  background:
    radial-gradient(120% 100% at 50% 0%, rgba(255,255,255,.92), rgba(244,246,250,.72) 62%, rgba(236,240,248,.55)),
    linear-gradient(180deg, #FFFFFF, #F4F6FA);
  border: 1px solid rgba(14, 31, 62, .10);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.9);
}
.omma-stage-quote { height: 300px; margin: 0; border-radius: 0; border-left: 0; border-right: 0; border-top: 0; }
.omma-stage-fit   { height: 240px; border-radius: 0; border: 0; border-bottom: 1px solid rgba(14,31,62,.08); }
.omma-stage-tool  { height: 220px; margin-bottom: 18px; }

/* a fine brass hairline on the top edge, the same detail the dark bands use */
.omma-stage::before {
  content: "";
  position: absolute; left: 0; right: 0; top: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(190, 146, 53, .5), transparent);
  z-index: 2;
}

.omma-stage-cap {
  position: absolute;
  right: 14px; bottom: 11px;
  z-index: 2;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #5A6A8C;
  pointer-events: none;
}
.omma-compass-label {
  position: absolute;
  left: 50%; bottom: 12px;
  transform: translateX(-50%);
  z-index: 2;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #96660F;
  white-space: nowrap;
  pointer-events: none;
  transition: opacity .3s ease;
}
.omma-compass-label:empty { opacity: 0; }

@media (max-width: 820px) {
  .omma-stage-quote { height: 210px; }
  .omma-stage-fit   { height: 180px; }
  .omma-stage-tool  { height: 165px; }
}

/* ---------- 3. MAGNETIC PRIMARY BUTTONS -----------------------------------
   The translate is layered on top of the existing hover lift rather than
   replacing it, so the site's own button motion is unchanged.               */
.omma-magnet { transform: translate(var(--mgx, 0px), var(--mgy, 0px)); }
.omma-magnet:hover { transform: translate(var(--mgx, 0px), calc(var(--mgy, 0px) - 2px)); }

/* ---------- 4. TRACKED SHEEN ON GLASS PANES -------------------------------
   Glass is never 3D-transformed here (Chrome glitches transformed
   backdrop-filter surfaces) — the depth comes from moving light instead.    */
.omma-sheen { position: relative; }
.omma-sheen::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 3;
  background: radial-gradient(420px circle at var(--ogx, 50%) var(--ogy, 50%),
              rgba(255, 255, 255, .55), rgba(255, 255, 255, .12) 40%, transparent 66%);
  opacity: 0;
  transition: opacity .35s ease;
}
.omma-sheen:hover::after { opacity: 1; }

/* ---------- 5. 3D CUBE STEP MARKERS ---------------------------------------
   The template's process cubes, applied to the step numbers this site already
   has. The number is repeated on the two faces that ever front the camera, so
   the step is readable at every point in the rotation.                      */
.omma-cube-slot {
  perspective: 520px;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  width: 38px; height: 38px;
  /* the slot inherits whatever the step number was styled as; the cube supplies
     its own face, so drop any inherited plate underneath it */
  background: none !important;
  border: 0 !important;
  box-shadow: none !important;
}
.omma-cube {
  position: relative;
  display: block;
  width: 30px; height: 30px;
  transform-style: preserve-3d;
  animation: ommaCube 14s linear infinite;
}
.omma-cube > i {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-style: normal;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .02em;
  color: #96660F;
  background: linear-gradient(150deg, rgba(255,255,255,.96), rgba(240,244,251,.9));
  border: 1px solid rgba(190, 146, 53, .38);
  border-radius: 3px;
  backface-visibility: hidden;
}
.omma-cube .f1 { transform: translateZ(15px); }
.omma-cube .f2 { transform: rotateY(90deg) translateZ(15px); }
.omma-cube .f3 { transform: rotateY(180deg) translateZ(15px); }
.omma-cube .f4 { transform: rotateY(-90deg) translateZ(15px); }
.omma-cube .f5 { transform: rotateX(90deg) translateZ(15px); }
.omma-cube .f6 { transform: rotateX(-90deg) translateZ(15px); }
@keyframes ommaCube {
  0%   { transform: rotateX(-16deg) rotateY(0deg); }
  100% { transform: rotateX(-16deg) rotateY(360deg); }
}

/* ---------- 6. LETTERED ANSWER KEYS ---------------------------------------- */
.omma-opt-key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  flex: 0 0 22px;
  margin-right: 12px;
  font-style: normal;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  font-weight: 500;
  color: #96660F;
  background: rgba(255, 255, 255, .9);
  border: 1px solid rgba(190, 146, 53, .38);
  border-radius: 6px;
  transition: background .18s ease, color .18s ease, border-color .18s ease;
}
.fit-opt:hover .omma-opt-key {
  background: #96660F;
  border-color: #96660F;
  color: #FFFFFF;
}

/* ---------- 7. FLOATING-LABEL FIELDS -------------------------------------
   The label rides on the field's top edge once there is focus or a value. The
   input keeps every attribute it shipped with — this is a wrapper, not a
   replacement.                                                              */
.omma-float { position: relative; display: block; }
.cap-row .omma-float { flex: 1 1 0; min-width: 0; }
.omma-float > input { width: 100%; }
.omma-float-label {
  position: absolute;
  left: 14px; top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
  font-size: 14.5px;
  line-height: 1;
  color: #4A5A7C;
  background: transparent;
  padding: 0 4px;
  transition: top .18s var(--ease-out, cubic-bezier(.16,1,.3,1)),
              font-size .18s ease, color .18s ease, background .18s ease;
}
.omma-float > input:focus + .omma-float-label,
.omma-float > input:not(:placeholder-shown) + .omma-float-label {
  top: 0;
  font-size: 10.5px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #96660F;
  background: #FFFFFF;
  border-radius: 3px;
}
/* a brass rule sweeps in under the focused field */
.omma-float::after {
  content: "";
  position: absolute;
  left: 10px; right: 10px; bottom: 0;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, #B07E22, #E0BE79);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .28s var(--ease-out, cubic-bezier(.16,1,.3,1));
  pointer-events: none;
}
.omma-float:focus-within::after { transform: scaleX(1); }

/* ---------- reduced motion / touch ----------------------------------------
   The module never boots in these cases, but if a preference changes after
   load the layer must go quiet rather than keep spinning.                   */
@media (prefers-reduced-motion: reduce) {
  .omma-stage { display: none !important; }
  .omma-card > .omma-card-gl, .omma-card > .omma-card-glare { display: none !important; }
  .omma-magnet { transform: none !important; }
  .omma-cube { animation: none !important; }
}

/* ============================================================================
   OMMA DESIGN LAYER — presentation for js/omma-design.js
   ----------------------------------------------------------------------------
   Unlike the section above, none of this is gated: it is ordinary CSS, costs
   nothing to run, and phones get it too. Everything is keyed to classes the
   design layer adds, so without that script the page is unchanged.
   ========================================================================== */

/* ---------- 8. PRODUCT TICKER --------------------------------------------
   The template's marquee, in the site's own key: mono, brass, hairline rules
   above and below, and quiet enough that it frames the cards rather than
   competing with the headline over them.                                    */
.omma-ticker {
  overflow: hidden;
  margin: 0 0 clamp(28px, 3.5vw, 44px);
  padding: 13px 0;
  border-top: 1px solid rgba(14, 31, 62, .10);
  border-bottom: 1px solid rgba(14, 31, 62, .10);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}
.omma-ticker-track {
  display: flex;
  align-items: center;
  gap: 26px;
  width: max-content;
  animation: ommaTicker 46s linear infinite;
}
.omma-ticker:hover .omma-ticker-track { animation-play-state: paused; }
.omma-ticker span {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11.5px;
  letter-spacing: .22em;
  color: #5A6A8C;
  white-space: nowrap;
}
.omma-ticker i {
  font-style: normal;
  font-size: 7px;
  color: #B07E22;
  opacity: .65;
}
/* the track holds the list twice, so -50% is exactly one loop */
@keyframes ommaTicker { to { transform: translateX(-50%); } }

/* ---------- 9. ESTIMATE BREAKDOWN BARS -----------------------------------
   Proportions of the controls the visitor already set — which lever is doing
   the work. Deliberately unlabelled: no second figure, no implied precision,
   and the q-note disclosure underneath still says what the estimate is.     */
.omma-bars {
  display: grid;
  gap: 9px;
  width: 100%;
  max-width: 320px;
  margin: 22px auto 4px;
  text-align: left;
}
.omma-bars-cap {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #5A6A8C;
  margin-bottom: 2px;
}
.omma-bar {
  display: grid;
  grid-template-columns: 68px minmax(0, 1fr);
  align-items: center;
  gap: 12px;
}
.omma-bar span {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #5A6A8C;
}
.omma-bar i {
  display: block;
  height: 4px;
  width: 20%;
  border-radius: 4px;
  background: linear-gradient(90deg, #B07E22, #E0BE79);
  transition: width .5s cubic-bezier(.22, 1, .36, 1);
}
@media (prefers-reduced-motion: reduce) { .omma-bar i { transition: none; } }

/* ---------- 10. STAGGERED 3D LIFT -----------------------------------------
   The grid tips back and flattens as it enters. Only applied to sets the site
   does not already drive with an inline transform.                          */
.omma-lift-set { perspective: 1200px; }
.omma-lift {
  opacity: 0;
  transform: translateY(26px) rotateX(11deg);
  transform-origin: 50% 0;
  transition: opacity .7s cubic-bezier(.16, 1, .3, 1),
              transform .7s cubic-bezier(.16, 1, .3, 1);
}
.omma-lift.in { opacity: 1; transform: none; }

/* the template's process cards lift on hover; the site's step cards now match */
.omma-lift-set > * { transition-property: opacity, transform, border-color, box-shadow; }
.book-point:hover, .bp-step:hover {
  border-color: rgba(190, 146, 53, .45);
}
.book-point { transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease; }
.book-point:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 34px -18px rgba(8, 18, 38, .35);
}
@media (prefers-reduced-motion: reduce) {
  .omma-lift { opacity: 1; transform: none; transition: none; }
  .book-point:hover { transform: none; }
}

/* ---------- 11. RANGE THUMB ------------------------------------------------
   The template's slider: a hairline track and a brass thumb sitting in a halo
   that grows on hover. The site used the native accent-color, which gives no
   affordance that the control is grabbable.                                 */
.q-field input[type=range] {
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  height: 22px;
}
.q-field input[type=range]::-webkit-slider-runnable-track {
  height: 3px;
  border-radius: 3px;
  background: linear-gradient(90deg, rgba(190, 146, 53, .55), rgba(14, 31, 62, .16));
}
.q-field input[type=range]::-moz-range-track {
  height: 3px;
  border-radius: 3px;
  background: linear-gradient(90deg, rgba(190, 146, 53, .55), rgba(14, 31, 62, .16));
}
.q-field input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 17px; height: 17px;
  margin-top: -7px;
  border: 0;
  border-radius: 50%;
  background: linear-gradient(180deg, #E0BE79, #B07E22);
  cursor: grab;
  box-shadow: 0 0 0 5px rgba(190, 146, 53, .15), 0 1px 3px rgba(8, 18, 38, .3);
  transition: box-shadow .2s ease;
}
.q-field input[type=range]::-moz-range-thumb {
  width: 17px; height: 17px;
  border: 0;
  border-radius: 50%;
  background: linear-gradient(180deg, #E0BE79, #B07E22);
  cursor: grab;
  box-shadow: 0 0 0 5px rgba(190, 146, 53, .15), 0 1px 3px rgba(8, 18, 38, .3);
}
.q-field input[type=range]:hover::-webkit-slider-thumb {
  box-shadow: 0 0 0 10px rgba(190, 146, 53, .20), 0 1px 3px rgba(8, 18, 38, .3);
}
.q-field input[type=range]:active::-webkit-slider-thumb { cursor: grabbing; }
.q-field input[type=range]:focus-visible::-webkit-slider-thumb {
  box-shadow: 0 0 0 4px #FFFFFF, 0 0 0 7px #B07E22;
}

/* ---------- 12. ERROR SHAKE ------------------------------------------------
   Motion only. The message and its aria-live announcement are the site's own
   and are untouched, so the error still reads for anyone who never sees this. */
.omma-shake { animation: ommaShake .4s cubic-bezier(.36, .07, .19, .97); }
@keyframes ommaShake {
  10%, 90% { transform: translateX(-1.5px); }
  20%, 80% { transform: translateX(3px); }
  30%, 50%, 70% { transform: translateX(-5px); }
  40%, 60% { transform: translateX(5px); }
}
@media (prefers-reduced-motion: reduce) { .omma-shake { animation: none; } }
