/* ==========================================================================
   vihaan.md — shared stylesheet
   Design system: design-system/vihaan-md/MASTER.md
   Style: Minimalism & Swiss, rendered as an engineering blueprint pad.

   Three themes on [data-theme]: blue (default), dark, light.
   Every theme swaps the same four ideas: pad, grid lines, ink, frame.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Archivo:wght@300;400;500;600;700&family=Space+Grotesk:wght@300;400;500;600;700&display=swap');

/* --- Tokens -------------------------------------------------------------- */

:root {
  /* Type. Chrome uses a system mono stack — no extra font download. */
  --font-display: 'Space Grotesk', system-ui, sans-serif;
  --font-body: 'Archivo', system-ui, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;

  /* Grid geometry. 5 minor cells per major cell, as on a real pad. */
  --grid-minor: 24px;
  --grid-major: 120px;

  --frame-inset: clamp(12px, 2.5vw, 28px);

  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  --duration: 220ms;
  --duration-slow: 420ms;
}

/* Blue — the default blueprint.
   Pad blue is deliberately deeper than a stock blueprint scan: white body text
   needs 4.5:1, and the brighter blues only reach ~3.5:1. */
:root,
[data-theme='blue'] {
  --pad: #2b72d6;
  --ink: #ffffff;
  --ink-muted: rgba(255, 255, 255, 0.72);
  --line-minor: rgba(255, 255, 255, 0.22);
  --line-major: rgba(255, 255, 255, 0.42);
  --frame: rgba(255, 255, 255, 0.55);
  --surface: rgba(19, 56, 110, 0.92);
  --surface-border: rgba(255, 255, 255, 0.28);

  --swatch-ink: #ffffff;
  --swatch-cyan: #7ee7f5;
  --swatch-amber: #ffd166;
  --swatch-rose: #ff8fa3;
}

[data-theme='dark'] {
  --pad: #0a0a0b;
  --ink: #fafafa;
  --ink-muted: rgba(250, 250, 250, 0.66);
  --line-minor: rgba(255, 255, 255, 0.10);
  --line-major: rgba(255, 255, 255, 0.22);
  --frame: rgba(255, 255, 255, 0.34);
  --surface: rgba(24, 24, 27, 0.94);
  --surface-border: rgba(255, 255, 255, 0.18);

  --swatch-ink: #fafafa;
  --swatch-cyan: #22d3ee;
  --swatch-amber: #fbbf24;
  --swatch-rose: #fb7185;
}

[data-theme='light'] {
  --pad: #ffffff;
  --ink: #2563eb;
  --ink-muted: rgba(37, 99, 235, 0.72);
  --line-minor: rgba(37, 99, 235, 0.16);
  --line-major: rgba(37, 99, 235, 0.30);
  --frame: rgba(37, 99, 235, 0.45);
  --surface: rgba(255, 255, 255, 0.94);
  --surface-border: rgba(37, 99, 235, 0.28);

  --swatch-ink: #2563eb;
  --swatch-cyan: #0891b2;
  --swatch-amber: #b45309;
  --swatch-rose: #be123c;
}

/* --- Reset --------------------------------------------------------------- */

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

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

body {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  overflow: hidden;
  background-color: var(--pad);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  transition: background-color var(--duration-slow) var(--ease),
    color var(--duration-slow) var(--ease);
}

/* --- Blueprint grid ------------------------------------------------------
   Four repeating gradients: minor verticals, minor horizontals, then the
   heavier major pair on top. Fixed layer, so it never scrolls out from under
   the drawing canvas.
   -------------------------------------------------------------------------- */

.grid {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(to right, var(--line-minor) 0 1px, transparent 1px 100%),
    repeating-linear-gradient(to bottom, var(--line-minor) 0 1px, transparent 1px 100%),
    repeating-linear-gradient(to right, var(--line-major) 0 1.5px, transparent 1.5px 100%),
    repeating-linear-gradient(to bottom, var(--line-major) 0 1.5px, transparent 1.5px 100%);
  background-size:
    var(--grid-minor) var(--grid-minor),
    var(--grid-minor) var(--grid-minor),
    var(--grid-major) var(--grid-major),
    var(--grid-major) var(--grid-major);
}

/* The drafting frame — the ruled border on a real pad. */
.frame {
  position: fixed;
  inset: var(--frame-inset);
  z-index: 1;
  pointer-events: none;
  border: 1.5px solid var(--frame);
}

/* --- Drawing surface ------------------------------------------------------ */

.pad {
  position: fixed;
  inset: 0;
  z-index: 2;
  /* Stops the browser panning/zooming instead of letting us draw. */
  touch-action: none;
  cursor: crosshair;
}

/* --- Chrome layer --------------------------------------------------------- */

/* Chrome sits above the canvas. The wrapper ignores pointer events so drawing
   works in the gaps; children opt back in individually. */
.chrome {
  position: fixed;
  inset: 0;
  z-index: 3;
  display: grid;
  grid-template-columns: auto auto;
  grid-template-rows: auto 1fr auto;
  gap: 1rem;
  /* Corner items align to the drafting frame: the frame's own inset plus a
     small gutter, so their text edges sit just inside the ruled border. */
  padding: calc(var(--frame-inset) + 0.625rem);
  pointer-events: none;
}

.chrome > * {
  pointer-events: auto;
}

.chrome__tl { grid-column: 1; grid-row: 1; justify-self: start; }
.chrome__tr { grid-column: 2; grid-row: 1; justify-self: end; }
.chrome__br { grid-column: 2; grid-row: 3; justify-self: end; align-self: end; }
.chrome__bl { grid-column: 1; grid-row: 3; justify-self: start; align-self: end; }

/* --- Breadcrumb ----------------------------------------------------------- */

.crumb {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  letter-spacing: 0.01em;
  color: var(--ink-muted);
}

.crumb a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color var(--duration) var(--ease);
}

.crumb a:hover {
  border-bottom-color: var(--ink);
}

.crumb__sep {
  opacity: 0.5;
}

.crumb__current {
  color: var(--ink);
}

/* --- Bracket button ------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  /* No horizontal padding: the chrome's padding sets the alignment line, so
     button text lines up with the breadcrumb and the theme switch. */
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  text-decoration: none;
  cursor: pointer;
  transition: opacity var(--duration) var(--ease);
}

.btn:hover {
  opacity: 0.7;
}

/* Brackets are decorative punctuation — hidden from screen readers so the
   label reads as "daily log", not "bracket daily log bracket". */
.btn::before,
.btn::after {
  display: inline-block;
  opacity: 0.55;
  transition: transform var(--duration) var(--ease);
}

.btn::before {
  content: '[';
  margin-right: 0.4em;
}

.btn::after {
  content: ']';
  margin-left: 0.4em;
}

.btn:hover::before {
  transform: translateX(-2px);
}

.btn:hover::after {
  transform: translateX(2px);
}

/* --- Copy-to-clipboard ---------------------------------------------------- */

.copy {
  position: relative;
}

.copy__label {
  display: inline-block;
  transition: opacity var(--duration) var(--ease);
}

.copy.is-copied .copy__label {
  opacity: 0;
}

.copy__confirm {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity var(--duration) var(--ease);
  pointer-events: none;
}

.copy.is-copied .copy__confirm {
  opacity: 1;
}

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

.hero {
  grid-column: 1 / -1;
  grid-row: 2;
  align-self: center;
  justify-self: center;
  text-align: center;
  pointer-events: none;
}

.wordmark {
  font-family: var(--font-display);
  font-size: clamp(2.75rem, 13vw, 8rem);
  font-weight: 500;
  letter-spacing: -0.04em;
  line-height: 1;
  white-space: nowrap;
}

/* The TLD sits smaller than the name but on the same baseline, so the pair
   still reads as one domain rather than two words. */
.wordmark__tld {
  font-size: 0.58em;
  font-weight: 300;
  opacity: 0.62;
}

.tagline {
  margin: 1rem auto 0;
  max-width: 34ch;
  color: var(--ink-muted);
  font-size: clamp(0.9375rem, 2.5vw, 1.0625rem);
  text-wrap: balance;
}

/* scrambleText swaps in placeholder glyphs of varying width; a fixed min-height
   stops the line count from jittering the layout mid-animation. */
.tagline {
  min-height: 3.2em;
}

/* --- Solid call-to-action ------------------------------------------------- */

/* Inverted fill: ink becomes the background and the pad colour becomes the
   text, which keeps contrast well past 4.5:1 in all three themes. */
.cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  margin-top: 1.75rem;
  padding: 0 1.5rem;
  border: 1.5px solid var(--ink);
  background: var(--ink);
  color: var(--pad);
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  text-decoration: none;
  cursor: pointer;
  /* The hero is pointer-transparent so you can draw through it; the button
     itself has to opt back in. */
  pointer-events: auto;
  transition: transform var(--duration) var(--ease),
    box-shadow var(--duration) var(--ease);
}

.cta:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 0 0 color-mix(in srgb, var(--ink) 35%, transparent);
}

.cta:active {
  transform: translateY(0);
  box-shadow: none;
}

/* --- Document pages (log) ------------------------------------------------- */

/* The landing page locks scrolling so drawing can't pan the view. Document
   pages need it back. */
.body--scroll {
  overflow-y: auto;
}

/* Doc chrome keeps the full-viewport fixed grid (so the theme switch stays
   pinned bottom-left) — the wrapper ignores pointer events, so the page still
   scrolls underneath it. */

.doc {
  position: relative;
  z-index: 3;
  max-width: 52rem;
  margin: 0 auto;
  padding: calc(var(--frame-inset) + 5.5rem) calc(var(--frame-inset) + 1.25rem) 6rem;
}

.doc__title {
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 7vw, 3.75rem);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1.05;
}

.doc__lede {
  margin-top: 0.75rem;
  color: var(--ink-muted);
  font-size: 1.0625rem;
}

.entries {
  margin-top: 3.5rem;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.entry {
  padding: 1.5rem;
  background: var(--surface);
  border: 1.5px solid var(--surface-border);
}

.entry__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.875rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--surface-border);
}

.entry__date {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--ink-muted);
}

.entry__title {
  font-family: var(--font-display);
  font-size: 1.375rem;
  font-weight: 500;
  letter-spacing: -0.01em;
}

.entry__section {
  margin-top: 1.25rem;
}

.entry__label {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 0.625rem;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  list-style: none;
}

.chip {
  padding: 0.25rem 0.625rem;
  border: 1px solid var(--surface-border);
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  /* Chips are short labels — keep them from breaking mid-word. */
  white-space: nowrap;
}

.links {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.links a {
  color: var(--ink);
  font-size: 0.9375rem;
  text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--ink) 40%, transparent);
  /* Long URLs as labels shouldn't force horizontal scroll. */
  overflow-wrap: anywhere;
  transition: border-color var(--duration) var(--ease);
}

.links a::before {
  content: '→ ';
  opacity: 0.55;
}

.links a:hover {
  border-bottom-color: var(--ink);
}

.entry__note {
  font-size: 0.9375rem;
  line-height: 1.65;
  max-width: 68ch;
}

.entry__note + .entry__note {
  margin-top: 0.75rem;
}

/* --- Tool palette ---------------------------------------------------------
   Fixed-position, dragged by its grip. JS writes --x/--y; the transform reads
   them, so dragging never touches layout.
   -------------------------------------------------------------------------- */

.palette {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 4;
  width: max-content;
  transform: translate3d(var(--x, 0px), var(--y, 0px), 0);
  background: var(--surface);
  border: 1.5px solid var(--surface-border);
  color: var(--ink);
  backdrop-filter: blur(6px);
  user-select: none;
}

.palette__grip {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0.25rem 0.25rem 0.5rem;
  border-bottom: 1px solid var(--surface-border);
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  cursor: grab;
  touch-action: none;
}

.palette__title {
  flex: 1;
}

.palette__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
  cursor: pointer;
}

.palette__toggle svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform var(--duration) var(--ease);
}

/* Chevron points down when open, up when collapsed. */
.palette__toggle[aria-expanded='false'] svg {
  transform: rotate(180deg);
}

.palette.is-collapsed .palette__grip {
  border-bottom-color: transparent;
}

.palette.is-collapsed .palette__body {
  display: none;
}

.palette.is-dragging .palette__grip {
  cursor: grabbing;
}

.palette__dots {
  display: flex;
  gap: 3px;
}

.palette__dots span {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.6;
}

.palette__body {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.5rem;
}

.palette__row {
  display: flex;
  gap: 0.25rem;
}

/* Control size is pointer-dependent: compact for a mouse, finger-sized for
   touch. --hit is bumped to 44px under (pointer: coarse) below. */
:root {
  --hit: 36px;
}

.tool {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--hit);
  height: var(--hit);
  padding: 0;
  border: 1.5px solid transparent;
  background: none;
  color: var(--ink);
  cursor: pointer;
  transition: border-color var(--duration) var(--ease),
    background-color var(--duration) var(--ease);
}

.tool:hover {
  background: color-mix(in srgb, var(--ink) 12%, transparent);
}

.tool[aria-pressed='true'] {
  border-color: var(--ink);
  background: color-mix(in srgb, var(--ink) 16%, transparent);
}

.tool svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Color swatches. The ring, not just the fill, marks selection — color alone
   would be the one cue a colorblind visitor can't read. */
.swatch {
  width: var(--hit);
  height: var(--hit);
  padding: 0;
  border: 1.5px solid transparent;
  background: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: border-color var(--duration) var(--ease);
}

.swatch::after {
  content: '';
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--swatch);
  border: 1px solid color-mix(in srgb, var(--ink) 35%, transparent);
  transition: transform var(--duration) var(--ease);
}

.swatch:hover::after {
  transform: scale(1.12);
}

.swatch[aria-pressed='true'] {
  border-color: var(--ink);
}

.swatch[aria-pressed='true']::after {
  transform: scale(1.12);
}

.palette__size {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0 0.125rem;
}

.palette__size label {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  color: var(--ink-muted);
}

.palette__size input {
  width: 92px;
  accent-color: var(--ink);
  cursor: pointer;
}

/* --- Theme switch --------------------------------------------------------- */

.themes {
  display: flex;
  border: 1.5px solid var(--surface-border);
  /* Opaque: on the log page this floats over scrolling text, and on the pad it
     can float over a drawing. Transparent would let both bleed through. */
  background: var(--surface);
  backdrop-filter: blur(6px);
}

.themes__btn {
  min-width: 44px;
  height: 44px;
  padding: 0 0.625rem;
  border: 0;
  background: none;
  color: var(--ink-muted);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color var(--duration) var(--ease),
    color var(--duration) var(--ease);
}

.themes__btn:hover {
  color: var(--ink);
  background: color-mix(in srgb, var(--ink) 10%, transparent);
}

.themes__btn[aria-pressed='true'] {
  color: var(--ink);
  background: color-mix(in srgb, var(--ink) 18%, transparent);
}

/* --- Accessibility -------------------------------------------------------- */

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

/* Intro reveal starts hidden only when JS is present to un-hide it. Without
   JS the content renders normally instead of staying invisible forever.
   The .is-revealed escape hatch is what the watchdog in intro.js sets, so a
   stalled animation can't leave the page blank. */
html.js:not(.is-revealed) [data-reveal] {
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  html.js [data-reveal] {
    opacity: 1;
  }
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* --- Touch devices --------------------------------------------------------
   Finger targets need to be bigger than mouse targets. Keyed off the pointer
   type rather than width, so a small window on a laptop keeps compact
   controls and a large tablet still gets finger-sized ones.
   -------------------------------------------------------------------------- */

@media (pointer: coarse) {
  :root {
    --hit: 44px;
  }

  .tool svg {
    width: 20px;
    height: 20px;
  }

  .swatch::after {
    width: 22px;
    height: 22px;
  }

  .palette__toggle {
    width: 40px;
    height: 40px;
  }
}

/* --- Small screens -------------------------------------------------------- */

@media (max-width: 640px) {
  :root {
    --grid-minor: 18px;
    --grid-major: 90px;
  }

  .chrome {
    padding: calc(var(--frame-inset) + 0.5rem);
  }

  .crumb,
  .btn {
    font-size: 0.75rem;
  }

  .tagline {
    max-width: 30ch;
  }
}

/* Below ~520px the bottom-left theme switch and bottom-right email can no
   longer share a row without overlapping, so they stack and centre instead. */
@media (max-width: 520px) {
  .chrome {
    grid-template-rows: auto 1fr auto auto;
    row-gap: 0.5rem;
  }

  .chrome__br {
    grid-column: 1 / -1;
    grid-row: 3;
    justify-self: center;
  }

  .chrome__bl {
    grid-column: 1 / -1;
    grid-row: 4;
    justify-self: center;
  }

  .doc {
    padding-top: calc(var(--frame-inset) + 4.5rem);
  }
}

/* Very narrow: the full email no longer fits on one line at a legible size. */
@media (max-width: 380px) {
  .copy {
    font-size: 0.6875rem;
  }

  .themes__btn {
    padding: 0 0.4rem;
    font-size: 0.625rem;
  }
}
