/* ==========================================================================
   Alan Joshy — shared base
   Tokens, header, footer, buttons and the overlays every page uses.
   Page-specific layouts live in site.css.
   ========================================================================== */

:root {
  --font-display: 'Archivo', system-ui, sans-serif;
  --font-body: 'Instrument Sans', system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, monospace;
  --font-hand: 'Caveat', 'Segoe Script', cursive;

  --radius: 14px;
  --ease: cubic-bezier(.22, .68, .24, 1);
  --wrap: 1180px;
  --gutter: clamp(1.5rem, 4vw, 2.5rem);

  /* legacy names, still read by the hardware / map / perks pages */
  --rust: #6F6040;
  --backwater: #23262A;
}

html[data-theme="light"] { color-scheme: light; }
/* Light ("bone"): warm grey paper, graphite ink, one muted bronze for small highlights. */
html[data-theme="light"] {
  --bg: #F9F8F5;
  --bg-2: #F2F1ED;
  --bg-3: #E7E5E0;
  --fg: #1A1B1E;
  --fg-dim: #38393E;
  --fg-faint: #4A4C51;
  --accent: #1A1B1E;
  --accent-text: #5E5136;
  --accent-strong: #000000;
  --on-accent: #F5F3EE;
  --green: #23262A;
  --green-ink: #F2F0EB;
  --card-bg: #FFFFFF;
  --card-border: rgba(26, 27, 30, .14);
  --line: rgba(26, 27, 30, .2);
  --panel: #1F2226;
  --panel-fg: #F9F8F5;
  --panel-dim: #CBC9C3;
  --hl: #E3D3B0;
  --foot-bg: #1F2226;
  --foot-fg: #F9F8F5;
  --foot-dim: #C2C0BA;
  --shadow: 0 22px 44px -28px rgba(26, 27, 30, .5);
  --chip-a: #4C4F56;   /* the charcoal icon tiles and the big "150+" */
  --chip-b: #131416;
  --chip-fg: #E6E8EC;
}

*,
*::before,
*::after {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

/* The full-screen tool pages (hardware lab, map, perks) keep their quiet, bar-free look */
.hw-body *,
.map-body *,
.fmp-body * {
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.hw-body *::-webkit-scrollbar,
.map-body *::-webkit-scrollbar,
.fmp-body *::-webkit-scrollbar {
  display: none;
}

/* nothing on the site can be selected or copied, except text inside form fields */
html,
body {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

input,
textarea,
select,
a[href^="tel:"],
a[href^="tel:"] *,
a[href^="mailto:"],
a[href^="mailto:"] * {
  -webkit-user-select: text;
  user-select: text;
}

/* so that dragging across a phone number or email selects it instead of dragging the link away */
a[href^="tel:"],
a[href^="mailto:"] {
  -webkit-user-drag: none;
}

::selection {
  background: color-mix(in srgb, var(--accent) 32%, transparent);
  color: inherit;
}

html {
  scroll-behavior: smooth;
  scrollbar-width: thin;
  scrollbar-color: var(--bg-3) transparent;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  transition: background .4s var(--ease), color .4s var(--ease);
}

a {
  color: inherit;
  text-decoration: none;
}

img,
svg {
  max-width: 100%;
  display: block;
}

img {
  height: auto;
  -webkit-user-drag: none;
}

em {
  font-style: italic;
}

:focus-visible {
  outline: 2px solid var(--accent-text);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip-link {
  position: absolute;
  left: 1rem;
  top: -4rem;
  z-index: 300;
  background: var(--fg);
  color: var(--bg);
  padding: .6rem 1rem;
  border-radius: 8px;
  transition: top .2s var(--ease);
}

.skip-link:focus {
  top: 1rem;
}

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding-inline: var(--gutter);
}

/* ---- small shared bits (the map / hardware pages also use these) ---- */
.hand {
  font-family: var(--font-hand);
  font-weight: 500;
  font-size: 1.5rem;
  line-height: 1.1;
  color: var(--accent-text);
}

.reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .9s var(--ease), transform .9s var(--ease);
}

.reveal.is-visible {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ---- buttons & links ---- */
.btn-cta,
.btn-line {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: .95rem;
  letter-spacing: .005em;
  padding: .72rem 1.4rem;
  border-radius: 6px;
  cursor: pointer;
  white-space: nowrap;
  border: 1.5px solid var(--accent);
  transition: transform .3s var(--ease), background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}

.btn-cta {
  background: var(--accent);
  color: var(--on-accent);
}

.btn-cta:hover {
  background: var(--accent-strong);
  border-color: var(--accent-strong);
  transform: translateY(-2px);
}

.btn-line {
  background: transparent;
  color: var(--fg);
  border-color: var(--line);
}

.btn-line:hover {
  border-color: var(--accent-text);
  color: var(--accent-text);
  transform: translateY(-2px);
}

.btn-full {
  width: 100%;
}

/* a plain, underlined link — the default way to point somewhere */
.text-link {
  font-weight: 600;
  background: linear-gradient(currentColor, currentColor) 0 100% / 100% 1.5px no-repeat;
  padding-bottom: 2px;
  transition: color .25s var(--ease), background-size .3s var(--ease);
}

.text-link:hover {
  color: var(--accent-text);
}

/* legacy arrow link, still used by the map page scripts */
/* ---- scroll progress ---- */
.scroll-progress-bar {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  width: 100%;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  z-index: 10000;
  pointer-events: none;
}

/* ==========================================================================
   Header
   ========================================================================== */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  border-bottom: 1px solid transparent;
  transition: background .35s var(--ease), border-color .35s var(--ease), transform .4s var(--ease);
}

.site-header.scrolled {
  background: var(--bg);
  border-bottom-color: var(--card-border);
}

.header-inner {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: .85rem var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
}

.brand {
  font-family: var(--font-body);
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: -.005em;
}

/* Header name: "AJ" at the top, spelling out to "Alan Joshy" on scroll.
   Same motion as the Anthropic logo: every letter glides along one ease-in-out curve
   (0.6s), the extra letters fade over half of it, and the J slides in next to the A.
   The box keeps the full-name width, so nothing else in the bar ever moves. */
.brand-morph {
  position: relative;
  display: inline-block;
  font-size: 1.3rem;
  font-weight: 700;
  line-height: 1.4;
  white-space: nowrap;
}

.brand-morph .ch {
  display: inline-block;
  white-space: pre;
}

.brand-morph.ready .ch {
  transform: translateX(var(--dx, 0px));
}

/* transitions switch on only after the first measurement, so nothing animates on page load */
.brand-morph.ready.anim .ch {
  transition: transform .4s cubic-bezier(.77, 0, .175, 1), opacity .2s linear;
}

/* letters other than the A and J are hidden while collapsed */
.brand-morph.ready .ch[data-k="x"] {
  opacity: 0;
}

.site-header.scrolled .brand-morph.ready .ch {
  transform: none;
}

.site-header.scrolled .brand-morph.ready .ch[data-k="x"] {
  opacity: 1;
}

.site-header.scrolled .brand-morph.ready.anim .ch[data-k="x"] {
  transition: transform .4s cubic-bezier(.77, 0, .175, 1), opacity .2s linear .2s;
}

@media (prefers-reduced-motion: reduce) {
  .brand-morph.ready.anim .ch,
  .site-header.scrolled .brand-morph.ready.anim .ch[data-k="x"] {
    transition: none;
  }
}

.main-nav {
  display: flex;
  gap: 2rem;
}

.main-nav a {
  position: relative;
  font-size: .98rem;
  font-weight: 500;
  color: var(--fg-dim);
  padding: .2rem 0;
  transition: color .25s var(--ease);
}

.main-nav a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -3px;
  height: 2px;
  background: var(--accent-text);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .35s var(--ease);
}

.main-nav a:hover,
.main-nav a[aria-current="page"] {
  color: var(--fg);
}

.main-nav a:hover::after,
.main-nav a[aria-current="page"]::after {
  transform: scaleX(1);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: .9rem;
}

.header-actions .btn-cta {
  padding: .5rem 1.1rem;
  font-size: .9rem;
}

@media (max-width: 860px) {
  .main-nav {
    display: none;
  }

  .header-actions .btn-cta {
    display: none;
  }

  .header-inner {
    gap: 1rem;
  }
}

/* ==========================================================================
   Footer
   ========================================================================== */
.site-footer {
  position: relative;
  z-index: 2;
  background: var(--foot-bg);
  color: var(--foot-fg);
  padding: clamp(5.5rem, 10vw, 8rem) 0 2.5rem;
}

.footer-top {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 3rem;
  padding-bottom: clamp(3.5rem, 6vw, 5rem);
  border-bottom: 1px solid color-mix(in srgb, var(--foot-fg) 18%, transparent);
}

.footer-brand .brand {
  display: inline-block;
  font-size: 1.25rem;
  margin-bottom: .6rem;
}

.footer-brand p {
  margin: 0;
  max-width: 30ch;
  color: var(--foot-dim);
  font-size: 1.02rem;
  line-height: 1.55;
}

.footer-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2rem;
  align-content: start;
}

.footer-cols .fh {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: 1.05rem;
  color: var(--foot-dim);
  margin: 0 0 .8rem;
}

.footer-cols ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: .45rem;
}

.footer-cols a {
  font-size: .98rem;
  transition: color .2s var(--ease);
}

.footer-cols a:hover {
  color: var(--hl);
}

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: .8rem 2rem;
  padding-top: 2.2rem;
  font-size: .86rem;
  color: var(--foot-dim);
}

.footer-bottom a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color .2s var(--ease);
}

.footer-bottom a:hover {
  color: var(--hl);
}

@media (max-width: 760px) {
  .footer-top {
    grid-template-columns: 1fr;
    gap: 2.4rem;
  }
}

/* ==========================================================================
   Floating contact button
   ========================================================================== */
.chat-fab-wrap {
  position: fixed;
  right: 1.4rem;
  bottom: 1.4rem;
  z-index: 150;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: .8rem;
  pointer-events: none;
}

.chat-fab {
  pointer-events: auto;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--bg) 85%, transparent), var(--shadow);
  transition: transform .3s var(--ease), background .3s var(--ease);
}

.chat-fab:hover {
  transform: translateY(-3px) rotate(-6deg);
  background: var(--accent-strong);
}

.chat-fab svg {
  width: 23px;
  height: 23px;
}

.fab-icon-close {
  display: none;
}

.chat-fab-wrap.open .fab-icon-chat {
  display: none;
}

.chat-fab-wrap.open .fab-icon-close {
  display: block;
}

.chat-popup {
  display: flex;
  flex-direction: column;
  gap: .3rem;
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: 16px;
  padding: .55rem;
  box-shadow: var(--shadow);
  min-width: 240px;
  opacity: 0;
  transform: translateY(10px) scale(.97);
  transform-origin: bottom right;
  pointer-events: none;
  transition: opacity .25s var(--ease), transform .25s var(--ease);
}

.chat-fab-wrap.open .chat-popup {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

.chat-popup-item {
  display: flex;
  align-items: center;
  gap: .8rem;
  padding: .65rem .75rem;
  border-radius: 11px;
  transition: background .2s var(--ease);
}

.chat-popup-item:hover {
  background: var(--bg-2);
}

.chat-popup-item strong {
  display: block;
  font-size: .95rem;
}

.chat-popup-item small {
  display: block;
  font-size: .8rem;
  color: var(--fg-dim);
}

.chat-popup-icon {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: #fff;
}

.chat-popup-icon svg {
  width: 19px;
  height: 19px;
}

.chat-popup-icon.wa {
  background: #1F8A4C;
}

.chat-popup-icon.mail {
  background: var(--green);
  color: var(--green-ink);
}

/* ==========================================================================
   Page-change overlays (bike → map)
   ========================================================================== */
.xpulse-ride-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity .25s ease;
}

.xpulse-ride-overlay.is-active {
  opacity: 1;
  pointer-events: auto;
}

.ride-smoke-curtain {
  position: absolute;
  inset: 0;
  background: var(--bg);
  opacity: 0;
  transform: scale(.9);
  filter: blur(35px);
  transition: opacity .55s ease .35s, transform .55s var(--ease) .35s;
}

.xpulse-ride-overlay.is-active .ride-smoke-curtain {
  opacity: 1;
  transform: none;
}

.ride-hud-toast {
  position: absolute;
  bottom: 12%;
  left: 50%;
  transform: translateX(-50%);
  z-index: 12;
  font-family: var(--font-hand);
  font-size: 1.9rem;
  color: var(--accent-text);
  opacity: 0;
  transition: opacity .35s ease .3s;
}

.xpulse-ride-overlay.is-active .ride-hud-toast {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .xpulse-ride-overlay {
    display: none !important;
  }
}

/* ==========================================================================
   404
   ========================================================================== */
.error-body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* the page content stretches, so the footer always sits at the bottom of the window */
.error-body main {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.error-section {
  flex: 1;
  display: flex;
  align-items: center;
  padding: 9rem 0 5rem;
  position: relative;
  z-index: 2;
}

.error-headline {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(3rem, 9vw, 7rem);
  line-height: .98;
  letter-spacing: -.03em;
  margin: 0 0 1.4rem;
}

.error-headline em {
  color: var(--accent-text);
}

.error-sub {
  color: var(--fg-dim);
  font-size: 1.15rem;
  max-width: 44ch;
  margin: 0 0 2rem;
}

.error-actions {
  display: flex;
  align-items: center;
  gap: 1.4rem;
  flex-wrap: wrap;
  margin-bottom: 2rem;
}

.error-aside {
  color: var(--fg-dim);
  margin: 0;
}

.error-inline-link {
  color: var(--accent-text);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ==========================================================================
   Phones and portrait tablets: the bottom tab bar, a floating glass pill
   Icons only. Idle tabs are outlines; the page you are on is solid, in a soft capsule.
   The names stay in the page for screen readers.
   ========================================================================== */
.tab-bar {
  display: none;
}

@media (max-width: 860px) {
  .tab-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: calc(10px + env(safe-area-inset-bottom));
    z-index: 160;
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    width: min(420px, calc(100% - 32px));
    margin-inline: auto;
    padding: .3rem .5rem;
    border: 1px solid color-mix(in srgb, var(--fg) 12%, transparent);
    border-radius: 31px;
    background: var(--card-bg);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .4), 0 18px 38px -16px rgba(0, 0, 0, .45);
  }

  .tab-bar a {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 52px;
    color: var(--fg-faint);
    transition: color .2s ease;
  }

  .tab-bar a[aria-current="page"] {
    color: var(--fg);
  }

  /* the page you're on: a soft capsule behind its icon */
  .tab-bar a[aria-current="page"]::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 60px;
    height: 42px;
    margin: -21px 0 0 -30px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--fg) 16%, transparent);
  }

  .tab-bar svg {
    position: relative;
    width: 25px;
    height: 25px;
    transition: transform .35s var(--ease);
  }

  .tab-bar a:active svg {
    transform: scale(.9);
  }

  .tab-bar .ico-f,
  .tab-bar a[aria-current="page"] .ico-o {
    display: none;
  }

  .tab-bar a[aria-current="page"] .ico-f {
    display: inline;
  }

  .tab-bar .ico-o path,
  .tab-bar .ico-o rect,
  .tab-bar .ico-o circle {
    fill: none;
    stroke: #2F3136;
    stroke-width: 1.9;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  .tab-bar .ico-f path,
  .tab-bar .ico-f rect {
    fill: var(--fg);
  }

  .tab-bar .ico-f .cut {
    fill: var(--card-bg);
  }

  /* names: kept for screen readers, not drawn */
  .tab-bar a > span {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }

  /* header: a little shorter, and no "Say hello" (the tab bar covers it) */
  .header-inner {
    padding: .84rem var(--gutter);
  }

  .brand {
    font-size: 1.08rem;
  }

  /* room under the page for the bar; the round contact button would sit on top of it */
  .site-footer {
    padding-bottom: calc(2.5rem + 80px + env(safe-area-inset-bottom));
  }

  .chat-fab-wrap {
    display: none;
  }

  /* pages slide in gently (opacity and transform only) */
  main {
    animation: page-in .3s var(--ease) both;
  }
}

@keyframes page-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  main { animation: none !important; }
}

/* ==========================================================================
   Frosted glass for the top bar (once you scroll) and the tab bar.
   Skipped on slow phones (html.lite, set by the script), with "reduce transparency", and where the browser can't blur.
   ========================================================================== */
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  html:not(.lite) .site-header.scrolled {
    background: color-mix(in srgb, var(--bg) 58%, transparent);
    -webkit-backdrop-filter: saturate(190%) blur(34px);
    backdrop-filter: saturate(190%) blur(34px);
  }

  @media (max-width: 860px) {
    html:not(.lite) .tab-bar {
      background: color-mix(in srgb, var(--card-bg) 54%, transparent);
      -webkit-backdrop-filter: saturate(200%) blur(30px);
      backdrop-filter: saturate(200%) blur(30px);
    }
  }

  @media (prefers-reduced-transparency: reduce) {
    html:not(.lite) .site-header.scrolled {
      background: var(--bg);
      -webkit-backdrop-filter: none;
      backdrop-filter: none;
    }

    html:not(.lite) .tab-bar {
      background: var(--card-bg);
      -webkit-backdrop-filter: none;
      backdrop-filter: none;
    }
  }
}

/* ==========================================================================
   Feedback while the next page loads (the script adds these classes)
   ========================================================================== */
.nav-progress {
  position: fixed;
  z-index: 500;
  top: 0;
  left: 0;
  width: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--fg), var(--accent-text));
  pointer-events: none;
}

html.is-navigating .tab-bar {
  pointer-events: none;
}

html.is-navigating a.is-tapped {
  opacity: .6;
  transform: scale(.94);
  transition: opacity .15s ease, transform .15s ease;
}

html.is-navigating main {
  opacity: .85;
  transition: opacity .25s ease;
}

@media (prefers-reduced-motion: reduce) {
  html.is-navigating a.is-tapped { transform: none; }
}
