:root {
  --bg: #f5f7f9;
  --ink: #111111;
  --chip-bg: rgba(255, 255, 255, 0.12);
  --ghost-bg: rgba(255, 255, 255, 0.1);
  --font: "Google Sans", "Product Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* Apple system blue. -dark is the resting bottom edge, -darker the hover
     face, -darkest the pressed face. */
  --accent: #0071e3;
  --accent-dark: #005bb8;
  --accent-darker: #0067d9;
  --accent-darkest: #005bb8;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; }

img { max-width: 100%; }

/* ---------- Shared bits ---------- */

/* Used by the topbars on the register / featured / profile pages. */
.logo { display: flex; align-items: center; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  white-space: nowrap;
  border-radius: 8px;
}

.btn-white {
  background: #fff;
  padding: 12px 24px;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.btn-white:hover, .btn-white:focus-visible {
  box-shadow: 0 6px 18px rgba(17, 17, 17, 0.08);
  transform: translateY(-1px);
}

.btn-ghost {
  background: var(--ghost-bg);
  border-radius: 8px;
  padding: 20px 32px;
  font-weight: 500;
  transition: background 0.15s ease, transform 0.15s ease;
}
.btn-ghost:hover, .btn-ghost:focus-visible {
  background: rgba(255, 255, 255, 0.2);
  transform: translateY(-1px);
}

/* ---------- Primary button ----------
   One style for every primary action on the site. Depth comes from stacked
   layers rather than a flat fill: a translucent wash over a light-to-dark
   gradient, an inset white top edge as the highlight, an inset dark bottom
   edge as the shadow under the lip.

   .btn-accent and .cta-btn-dark are kept as aliases so existing markup on
   every page picks this up without being rewritten. */

.btn-dark,
.btn-accent,
.cta-btn-dark {
  background:
    linear-gradient(#2020201a 0% 100%),
    linear-gradient(#4f4f4f 0%, #202020d9 100%);
  color: #fff;
  border: 1px solid #383838;
  border-radius: 8px;
  box-shadow:
    0 0 0 1px #4040401f,
    inset 0 2px #ffffff3d,
    inset 0 -0.5px 2px #00000040,
    0 2px 8px #00000008,
    0 3px 4px #00000029;
  padding: 14px 28px;
  font-size: 16px;
  font-weight: 500;
  transition: background 0.2s ease, box-shadow 0.2s ease;
}

/* Hover darkens the wash and brightens the top highlight, while the outer drop
   shadows fall away. The button settles into the page instead of lifting off it. */
.btn-dark:hover, .btn-dark:focus-visible,
.btn-accent:hover, .btn-accent:focus-visible,
.cta-btn-dark:hover, .cta-btn-dark:focus-visible {
  background:
    linear-gradient(#202020cc 0% 100%),
    linear-gradient(#4f4f4f 0%, #202020d9 100%);
  box-shadow:
    0 0 0 1px #4040401f,
    inset 0 2px #fff6,
    inset 0 -0.5px 2px #00000040;
}

/* The same recipe in green, for affirmative actions like accepting an offer.
   Every layer maps one to one onto the dark button's. */
.btn-green {
  background:
    linear-gradient(#2a9a5c1a 0% 100%),
    linear-gradient(#55cd92 0%, #2fa866d9 100%);
  color: #fff;
  border: 1px solid #3aa96b;
  border-radius: 8px;
  box-shadow:
    0 0 0 1px #2a8f541f,
    inset 0 2px #ffffff3d,
    inset 0 -0.5px 2px #00000040,
    0 2px 8px #00000008,
    0 3px 4px #00000029;
  padding: 14px 28px;
  font-size: 16px;
  font-weight: 500;
  transition: background 0.2s ease, box-shadow 0.2s ease;
}

.btn-green:hover, .btn-green:focus-visible {
  background:
    linear-gradient(#2a9a5c99 0% 100%),
    linear-gradient(#55cd92 0%, #2fa866d9 100%);
  box-shadow:
    0 0 0 1px #2a8f541f,
    inset 0 2px #fff6,
    inset 0 -0.5px 2px #00000040;
}

/* And in red, for undoing a choice. Same layers as the other two. */
.btn-red {
  background:
    linear-gradient(#b3261e1a 0% 100%),
    linear-gradient(#f0716b 0%, #d8433cd9 100%);
  color: #fff;
  border: 1px solid #d4534c;
  border-radius: 8px;
  box-shadow:
    0 0 0 1px #c243341f,
    inset 0 2px #ffffff3d,
    inset 0 -0.5px 2px #00000040,
    0 2px 8px #00000008,
    0 3px 4px #00000029;
  padding: 14px 28px;
  font-size: 16px;
  font-weight: 500;
  transition: background 0.2s ease, box-shadow 0.2s ease;
}

.btn-red:hover, .btn-red:focus-visible {
  background:
    linear-gradient(#b3261e99 0% 100%),
    linear-gradient(#f0716b 0%, #d8433cd9 100%);
  box-shadow:
    0 0 0 1px #c243341f,
    inset 0 2px #fff6,
    inset 0 -0.5px 2px #00000040;
}

/* ---------- Hero ---------- */

.hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  width: 100%;
  /* Breathing room where the navbar used to be, but kept in check: whatever
     the hero takes is taken away from the image below it on a one-screen page. */
  padding: clamp(32px, 7vh, 80px) 20px 0;
  text-align: center;
}

.wordmark { height: 31px; width: auto; opacity: 0; animation: rise 0.6s ease forwards; }

.hero-title {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 0;
  font-size: 56px;
  font-weight: 700;
  line-height: 1.1;
  opacity: 0;
  animation: rise 0.6s ease 0.08s forwards;
}
.hero-title .dot { width: 12px; height: 12px; }

.hero-subtitle {
  margin: 0;
  font-size: 24px;
  font-weight: 400;
  opacity: 0;
  animation: rise-fade 0.6s ease 0.16s forwards;
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 28px;
  opacity: 0;
  animation: rise 0.6s ease 0.24s forwards;
}

@keyframes rise {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes rise-fade {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 0.8; transform: translateY(0); }
}

/* ---------- Showcase ---------- */

.showcase {
  width: 100%;
  margin-top: clamp(20px, 4vh, 48px);
  padding: 0 20px clamp(20px, 4vh, 48px);
}

/* The landing page is a single screen: the hero takes the height it needs and
   the showcase claims whatever is left, so the image never forces a scroll.
   Letting flex measure it beats guessing the hero's height in CSS. */
.landing {
  /* A definite height, not min-height: the showcase below needs a resolved
     box to size the image against. min-height leaves it indefinite and the
     image falls back to its natural size. */
  height: 100vh;
  min-height: 560px;
  display: flex;
  flex-direction: column;
}
.landing .hero { flex: 0 0 auto; }
.landing .showcase {
  flex: 1 1 auto;
  /* Without this a flex item refuses to shrink below its content size. */
  min-height: 0;
}

/* On a narrow screen the collage is limited by width long before height, so
   pinning the page to 100vh would just leave dead space under it. Let the
   content set the height instead. */
@media (max-width: 880px) {
  .landing { height: auto; min-height: 0; }
  .landing .showcase { flex: 0 0 auto; }
  .showcase-img { height: auto; }
}

.showcase-img {
  display: block;
  width: 100%;
  height: 100%;
  /* The box fills the leftover space; contain fits the picture inside it
     without cropping or stretching. */
  object-fit: contain;
  object-position: center top;
  opacity: 0;
  animation: rise 0.7s ease 0.32s forwards;
}

@media (prefers-reduced-motion: reduce) {
  .wordmark, .hero-title, .hero-subtitle, .cta-row, .showcase-img {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
}

/* ---------- Responsive ---------- */

@media (max-width: 880px) {
  .hero { padding-top: 56px; }
  .hero-title { font-size: 40px; gap: 10px; }
  .hero-title .dot { width: 8px; height: 8px; }
  .hero-subtitle { font-size: 18px; }

  .btn-ghost { padding: 16px 24px; font-size: 14px; }
}

@media (max-width: 480px) {
  .hero { padding-top: 40px; }
  .hero-title { font-size: 30px; gap: 8px; }
  .cta-row { gap: 8px; }
}

/* Toast */

.toast {
  position: fixed;
  left: 50%;
  bottom: 28px;
  transform: translateX(-50%) translateY(16px);
  background: var(--ink);
  color: #fff;
  padding: 14px 22px;
  border-radius: 8px;
  font-size: 14px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
  z-index: 50;
}
.toast.is-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

.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;
}

/* ---------- Updates modal ---------- */

.modal-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(17, 17, 17, 0.32);
  opacity: 0;
  transition: opacity 0.2s ease;
  z-index: 100;
}
.modal-overlay[hidden] { display: none; }
.modal-overlay.is-visible { opacity: 1; }

.modal {
  position: relative;
  width: 100%;
  max-width: 420px;
  background: #fff;
  border-radius: 8px;
  padding: 40px 32px 32px;
  box-shadow: 0 24px 60px rgba(17, 17, 17, 0.18);
  transform: translateY(12px) scale(0.98);
  transition: transform 0.2s ease;
}
.modal-overlay.is-visible .modal { transform: translateY(0) scale(1); }

.modal h2 { margin: 0 0 8px; font-size: 22px; font-weight: 700; }
.modal p { margin: 0 0 20px; opacity: 0.75; font-size: 15px; line-height: 1.5; }

.modal-close {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  font-size: 20px;
  line-height: 1;
  transition: background 0.15s ease;
}
.modal-close:hover { background: var(--bg); }

#updatesForm {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
#updatesForm input {
  flex: 1 1 180px;
  min-width: 0;
  padding: 14px 18px;
  border: 1px solid rgba(17, 17, 17, 0.14);
  border-radius: 8px;
  font-family: inherit;
  font-size: 15px;
  color: var(--ink);
  background: var(--bg);
}
#updatesForm input:focus {
  outline: none;
  border-color: var(--ink);
}
#updatesForm .btn-dark { flex: 0 0 auto; }

.modal-note {
  margin: 14px 0 0;
  font-size: 14px;
  min-height: 20px;
  opacity: 0.85;
}
.modal-note.is-error { color: #c0392b; opacity: 1; }
.modal-note.is-success { color: #1f8a4c; opacity: 1; }

/* =============================================================================
   Apple interface polish, from the apple-design skill. Applied site-wide via
   this shared sheet. Button designs are untouched at rest; the skill only adds
   how things respond, read and layer:

   1. Size-specific tracking: negative for display text, none for body.
   2. Instant press response on pointer-down, not on release.
   3. Translucent chrome with backdrop-filter for hierarchy.
   4. Reduced motion falls back to crossfades, reduced transparency to solid.
   ============================================================================= */

:root { --spring: cubic-bezier(0.32, 0.72, 0, 1); }

/* ---------- Type: tracking tightens as text grows, line-height loosens as it
   shrinks. Page styles that set their own values still win over these. */

h1 { letter-spacing: -0.03em; line-height: 1.05; }
h2 { letter-spacing: -0.022em; line-height: 1.12; }
h3 { letter-spacing: -0.015em; line-height: 1.2; }
h4 { letter-spacing: -0.01em; }
body { letter-spacing: 0; }

/* ---------- Press response: interactive things acknowledge the pointer the
   moment it lands. The independent `scale` property is used so no button's
   own background or shadow transition gets overridden. */

button, .btn, .role-tab, .suggestion, .opt, .si-role {
  -webkit-tap-highlight-color: transparent;
}

button:not(:disabled):active,
.btn:active,
a.btn:active,
.si-role:active {
  scale: 0.97;
  transition: scale 0.06s var(--spring);
}

.icon-btn:active, .w-menu:active, .cs-theme-btn:active { scale: 0.9; }

/* ---------- Translucent chrome: the bars sit on the content as material, not
   paint. color-mix keeps them on each page's own token, so the dark landing
   stays dark. */

.app-topbar {
  background: color-mix(in srgb, var(--shell, #f1f1f2) 75%, transparent);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
}

.cs-topbar {
  background: color-mix(in srgb, var(--cs-bg, #f7f7f8) 65%, transparent);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
}

/* ---------- Focus: one visible ring everywhere, only for keyboard focus. */

:focus-visible {
  outline: 2px solid #0071e3;
  outline-offset: 2px;
}

/* ---------- Accessibility fallbacks the skill requires. */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  button:not(:disabled):active, .btn:active, a.btn:active { scale: 1; }
}

@media (prefers-reduced-transparency: reduce) {
  .app-topbar { background: var(--shell, #f1f1f2); backdrop-filter: none; -webkit-backdrop-filter: none; }
  .cs-topbar { background: var(--cs-bg, #f7f7f8); backdrop-filter: none; -webkit-backdrop-filter: none; }
  .ap-nav { background: #fff; backdrop-filter: none; -webkit-backdrop-filter: none; }
}

/* =============================================================================
   Micro interactions. Buttons rise a pixel to meet the pointer and settle on
   press; interactive icons answer with their own small move. Everything uses
   the independent translate/rotate/scale properties so no component's own
   background or shadow transitions get clobbered, and the reduced-motion
   block above already zeroes all of it.
   ============================================================================= */

/* The kit buttons: lift on hover, settle on press. The transition list repeats
   each kit button's own background and box-shadow so this later rule does not
   drop them. */
.btn {
  transition:
    background 0.2s ease,
    box-shadow 0.2s ease,
    translate 0.18s var(--spring),
    filter 0.18s ease;
}

@media (hover: hover) {
  .btn:not(:disabled):hover { translate: 0 -1px; filter: brightness(1.04); }
  .btn:not(:disabled):active { translate: 0 0; filter: brightness(0.98); }

  /* The brand mark gives a small tilt back. */
  .app-brand img, .ap-nav-brand img {
    transition: rotate 0.3s var(--spring), scale 0.3s var(--spring);
  }
  .app-brand:hover img, .ap-nav-brand:hover img { rotate: -6deg; scale: 1.08; }
}

/* One-shot icon moves, triggered by a state class landing on the element. */
@keyframes icon-pop {
  0% { scale: 1; }
  40% { scale: 1.35; }
  100% { scale: 1; }
}
@keyframes icon-pop-soft {
  0% { scale: 1; }
  40% { scale: 1.12; }
  100% { scale: 1; }
}
@keyframes icon-wiggle {
  0%, 100% { rotate: 0deg; }
  30% { rotate: -10deg; }
  65% { rotate: 7deg; }
}

/* =============================================================================
   Dark theme. The palette lives in gridma-theme.css (--dk-*); this section only
   maps the shared tokens and the hard-coded colors above onto it, so the light
   values stay exactly as they are.
   ============================================================================= */

/* Screen only: a printout keeps the light colors on white paper. */
@media screen {
  /* --ink is text almost everywhere, so it flips to the light ink. The few black
     faces that use it as a background invert with it (their text is set below or
     in their own sheet). */
  :root[data-theme="dark"] {
    --bg: var(--dk-page);
    --ink: var(--dk-ink);
  }

  /* The white button turns into a dark one: a raised dark face, a light edge and
     a faint top highlight in place of the white one. */
  :root[data-theme="dark"] .btn-white {
    background: var(--dk-surface-2);
    color: var(--dk-ink);
    box-shadow: inset 0 0 0 1px var(--dk-line-2), inset 0 1px var(--dk-tint);
  }
  :root[data-theme="dark"] .btn-white:hover,
  :root[data-theme="dark"] .btn-white:focus-visible {
    background: var(--dk-surface-3);
    box-shadow: inset 0 0 0 1px var(--dk-line-2), inset 0 1px var(--dk-tint), 0 6px 18px var(--dk-shadow);
  }

  /* The black primary button inverts: a light face with dark text, the same
     layered build (a soft shade top to bottom, a dark lip under it). The page
     color under the shade keeps the face the same on any background. */
  :root[data-theme="dark"] :is(.btn-dark, .btn-accent, .cta-btn-dark) {
    background:
      linear-gradient(var(--dk-ink) 0%, var(--dk-ink-2) 100%),
      linear-gradient(var(--dk-page) 0 0);
    color: var(--dk-on-ink);
    border-color: var(--dk-ink-2);
    box-shadow:
      0 0 0 1px var(--dk-line),
      inset 0 -0.5px 2px var(--dk-shadow),
      0 3px 4px var(--dk-shadow);
  }
  /* Hover settles the face a step down, as the light button does. */
  :root[data-theme="dark"] :is(.btn-dark, .btn-accent, .cta-btn-dark):is(:hover, :focus-visible) {
    background:
      linear-gradient(var(--dk-ink-2) 0 0),
      linear-gradient(var(--dk-page) 0 0);
    box-shadow:
      0 0 0 1px var(--dk-line),
      inset 0 -0.5px 2px var(--dk-shadow);
  }

  /* Toast: a raised dark card with an edge, so it reads over the cards too. */
  :root[data-theme="dark"] .toast {
    background: var(--dk-surface);
    color: var(--dk-ink);
    box-shadow: 0 0 0 1px var(--dk-line-2), 0 8px 24px var(--dk-shadow);
  }

  /* Updates modal. */
  :root[data-theme="dark"] .modal-overlay { background: var(--dk-scrim); }
  :root[data-theme="dark"] .modal {
    background: var(--dk-surface);
    box-shadow: 0 0 0 1px var(--dk-line), 0 24px 60px var(--dk-shadow);
  }
  :root[data-theme="dark"] .modal-close:hover { background: var(--dk-tint-2); }
  :root[data-theme="dark"] #updatesForm input {
    background: var(--dk-surface-2);
    border-color: var(--dk-line-2);
  }
  :root[data-theme="dark"] #updatesForm input:focus { border-color: var(--dk-ink); }
  :root[data-theme="dark"] .modal-note.is-error { color: var(--dk-danger); }
  :root[data-theme="dark"] .modal-note.is-success { color: var(--dk-success); }

  /* The keyboard ring: a lighter blue reads better on the dark surfaces. :where
     keeps it as weak as the light rule, so a sheet's own ring still wins. */
  :where(:root[data-theme="dark"]) :focus-visible { outline-color: var(--dk-link); }

  /* The translucent bars fall back to the dark page when no page color is set. */
  :root[data-theme="dark"] .cs-topbar { background: color-mix(in srgb, var(--cs-bg, var(--dk-page)) 65%, transparent); }

  @media (prefers-reduced-transparency: reduce) {
    :root[data-theme="dark"] .cs-topbar { background: var(--cs-bg, var(--dk-page)); }
    :root[data-theme="dark"] .ap-nav { background: var(--dk-surface); }
  }
}

@media screen {
  /* The green and red faces are bright on the dark page: dark text reads
     on them (white is about 2.5:1 on the green). */
  :root[data-theme="dark"] :is(.btn-green, .btn-red) { color: var(--dk-on-ink); }
}
