/* ════════════════════════════════════════════════════════════════════════
   danidoes.dev — a designer's index.
   Paper & ink. Serif display type, hairline rules, one drop of red.
   Day is an etching; night is its negative.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  --paper: #f2efe8;
  --ink: #111008;
  --ink-mid: rgba(17, 16, 8, 0.68);
  --ink-dim: rgba(17, 16, 8, 0.42);
  --hairline: rgba(17, 16, 8, 0.85);
  --hairline-faint: rgba(17, 16, 8, 0.18);
  --red: #a31621;

  --serif: "Didot", "Bodoni MT", "Playfair Display", "Baskerville",
           Georgia, "Times New Roman", serif;
  --mono: ui-monospace, "Cascadia Mono", "Courier New", monospace;

  --dur: 0.25s;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

html.dark-mode {
  --paper: #0c0b09;
  --ink: #e9e4d8;
  --ink-mid: rgba(233, 228, 216, 0.68);
  --ink-dim: rgba(233, 228, 216, 0.4);
  --hairline: rgba(233, 228, 216, 0.8);
  --hairline-faint: rgba(233, 228, 216, 0.16);
  --red: #c42430;
}

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

html {
  scroll-behavior: smooth;
  overflow-x: hidden;
  max-width: 100%;
}

body {
  overflow-x: hidden;
  max-width: 100%;
}

::selection { background: var(--red); color: var(--paper); }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.container {
  position: relative;
  z-index: 1;
  max-width: 1020px;
  margin: 0 auto;
  padding: 0 1.75rem;
  overflow-wrap: break-word;
}

img, svg { max-width: 100%; }

.accent { color: inherit; font-style: italic; }

h1, h2, h3 { margin: 0; font-weight: 400; }

a { color: inherit; }

/* ── Small caps utility ─────────────────────────────────────────────── */
.smallcaps,
.nav-links a,
.btn,
.work-tab,
.coming-soon,
.site-footer {
  font-family: var(--serif);
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 0.72rem;
}

/* ── Header ─────────────────────────────────────────────────────────── */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--paper);
  border-bottom: 1px solid var(--hairline);
  transition: background var(--dur) var(--ease);
}

.nav {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 1.4rem;
  max-width: 1020px;
  margin: 0 auto;
  padding: 1rem 1.75rem;
}

.nav-logo {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.05rem;
  color: var(--ink);
  text-decoration: none;
  margin-right: auto;
}

/* Sits outside the collapsible menu so it's reachable without opening it.
   Ordered after nav-right so it lands at the far right on desktop; once
   nav-right leaves the flex flow (absolutely positioned) at the mobile
   breakpoint below, this naturally ends up just left of the hamburger. */
.theme-toggle { order: 2; }

/* Hamburger — hidden on wide screens, shown at the mobile breakpoint below */
.nav-toggle {
  order: 3;
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: flex-end;
  gap: 5px;
  width: 2rem;
  height: 2rem;
  padding: 0;
  background: none;
  border: none;
  cursor: pointer;
}
.nav-toggle span {
  display: block;
  width: 100%;
  height: 1px;
  background: var(--ink);
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease),
              width var(--dur) var(--ease);
}
.nav-toggle span:nth-child(2) { width: 70%; }
.nav-toggle[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(6px) rotate(45deg);
  width: 100%;
}
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) {
  transform: translateY(-6px) rotate(-45deg);
  width: 100%;
}

.nav-right { display: flex; align-items: baseline; gap: 1.4rem; }

.nav-links a {
  color: var(--ink-mid);
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}
.nav-links a:hover { color: var(--red); }

/* The glyph is the button's only content, so it carries its own size rather
   than the small-caps treatment the text label used to need. Swapping it from
   the dark-mode class (not from JS) keeps it right on the very first paint. */
.theme-toggle {
  background: none;
  border: none;
  padding: 0;
  font-size: 1rem;
  line-height: 1;
  color: var(--ink-mid);
  cursor: pointer;
  transition: color var(--dur) var(--ease);
}
.theme-toggle:hover { color: var(--red); }
.theme-toggle::before { content: "☾"; }
html.dark-mode .theme-toggle::before { content: "☀"; }

/* ── Hero ───────────────────────────────────────────────────────────── */
.hero {
  padding: 9rem 1.75rem 7rem;
}

.hero-kicker {
  font-family: var(--mono);
  /* This nowrap line is 35.7em of ink (40 mono chars + 0.3em tracking between
     them), so it only sits flush inside the 1.25rem gutters when the size is
     derived from the width — (100vw - 2.5rem) / 35.7 — rather than guessed.
     The old flat 2.6vw ramp overran the right gutter at every phone width. */
  font-size: clamp(0.46rem, calc(2.8vw - 1.12px), 0.72rem);
  text-transform: uppercase;
  letter-spacing: clamp(0.12em, 1.2vw, 0.3em);
  color: var(--ink-dim);
  margin: 0 0 2rem;
  white-space: nowrap;
}

.hero h1 {
  font-size: clamp(2.6rem, 7.5vw, 5.2rem);
  line-height: 1.06;
  letter-spacing: -0.015em;
}

.hero h1 .accent { font-style: italic; }

.hero-sub {
  margin: 2.25rem 0 0;
  max-width: 460px;
  color: var(--ink-mid);
  font-size: 1.02rem;
  font-style: italic;
}

.hero-actions {
  margin-top: 3rem;
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
}

/* ── Buttons ────────────────────────────────────────────────────────── */
.btn {
  display: inline-block;
  padding: 0.8rem 1.8rem;
  border: 1px solid var(--hairline);
  background: transparent;
  color: var(--ink);
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.btn:hover {
  background: var(--ink);
  color: var(--paper);
}

.btn-primary {
  background: var(--ink);
  color: var(--paper);
}
.btn-primary:hover {
  background: var(--red);
  border-color: var(--red);
  color: #f2efe8;
}

/* ── Sections ───────────────────────────────────────────────────────── */
section { padding: 3.5rem 1.75rem; }

h2 {
  font-size: 2rem;
  display: flex;
  align-items: baseline;
  gap: 1rem;
  margin-bottom: 2.5rem;
}

.section-num {
  font-family: var(--mono);
  font-size: 0.8rem;
  color: var(--ink-dim);
}

.section-sub {
  color: var(--ink-mid);
  font-style: italic;
  margin: -1.5rem 0 2.5rem;
  max-width: 560px;
  font-size: 0.95rem;
}

/* ── Index (tabs) ───────────────────────────────────────────────────── */
.work-tabs {
  display: flex;
  gap: 0;
  margin-bottom: 3.5rem;
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}

.work-tab {
  flex: 1;
  padding: 1.1rem 0.5rem;
  background: transparent;
  border: none;
  border-left: 1px solid var(--hairline-faint);
  color: var(--ink-dim);
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.work-tab:first-child { border-left: none; }
.work-tab:hover { color: var(--ink); }
.work-tab.is-active {
  background: var(--ink);
  color: var(--paper);
}

.work-panel { display: none; }
.work-panel.is-active {
  display: block;
  animation: panel-in 0.45s var(--ease);
}

@keyframes panel-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ── Project entries — editorial rows, not cards ────────────────────── */
.project-list { display: flex; flex-direction: column; }

.project-card {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border-bottom: 1px solid var(--hairline);
  padding: 3rem 0;
  gap: 2.5rem;
  min-width: 0;
}
.project-card > * { min-width: 0; }
.project-card:first-child { padding-top: 0.5rem; }
.project-card.reverse .project-visual { order: 2; }

.project-visual {
  min-height: 280px;
  display: flex;
  border: 1px solid var(--hairline);
}
.project-visual img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(28%) contrast(1.05);
  transition: filter var(--dur) var(--ease);
}
.project-card:hover .project-visual img { filter: none; }

.project-placeholder {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    repeating-linear-gradient(45deg,
      transparent 0 9px,
      var(--hairline-faint) 9px 10px);
}
.placeholder-name {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.9rem;
  color: var(--ink-dim);
  background: var(--paper);
  padding: 0.35rem 1.2rem;
  transition: background var(--dur) var(--ease);
}

.project-info { display: flex; flex-direction: column; align-items: flex-start; }

.project-info h3 {
  font-size: 2.1rem;
  line-height: 1.1;
  letter-spacing: -0.01em;
}

.project-tagline {
  font-style: italic;
  color: var(--red);
  font-size: 0.95rem;
  margin: 0.6rem 0 1.2rem;
}

.project-desc {
  color: var(--ink-mid);
  font-size: 0.95rem;
  margin: 0;
  overflow-wrap: break-word;
}

/* Tech as a printed colophon line, not pills */
.tech-list {
  list-style: none;
  width: 100%;
  margin: 1.5rem 0 1.8rem;
  padding: 0;
  font-family: var(--mono);
  /* Starting size. fitTechLists() in main.js shrinks from here per card,
     writing an inline font-size, whenever a row would not fit its column. */
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-dim);
  line-height: 2;
  /* Always one line. The "  ·  " separators are white-space: pre, so the
     only break opportunities in a row are the spaces inside multi-word tags
     — left to wrap, a long stack splits as "DJANGO / CHANNELS" and, where
     the remaining unbreakable run outgrows the column, bleeds past its edge.
     Shrinking the font is what keeps every stack on one line at any width;
     this replaces the old phone-only vw clamp, which left the mid-range
     two-column widths unhandled and depended on the viewport rather than on
     the column the row actually has to fit. */
  display: flex;
  flex-wrap: nowrap;
  white-space: nowrap;
}
/* flex-shrink: 0 so tags keep their natural width and the row's scrollWidth
   stays an honest measure of overflow for the fitter — otherwise flex would
   squeeze the items and spill their nowrap text instead. */
.tech-tag { flex: 0 0 auto; }
.tech-tag:not(:last-child)::after { content: "  ·  "; white-space: pre; }

.project-link {
  font-size: 0.72rem;
  max-width: 100%;
  overflow-wrap: break-word;
  word-break: break-word;
}

.coming-soon {
  display: inline-block;
  padding: 0.8rem 1.8rem;
  border: 1px dashed var(--ink-dim);
  color: var(--ink-dim);
}

/* ── Résumé teaser ──────────────────────────────────────────────────── */
.resume-teaser {
  padding-top: 3.5rem;
  padding-bottom: 3.5rem;
}
.resume-teaser h2 { margin-bottom: 1rem; }
.resume-teaser .section-sub { margin: 0 0 2.5rem; }
.resume-teaser .hero-actions {
  margin-top: 0;
  margin-bottom: 1rem;
}

/* ── Contact / footer ───────────────────────────────────────────────── */
.contact {
  text-align: center;
  padding: 5rem 1.75rem 6rem;
  border-top: 1px solid var(--hairline);
}
.contact h2 { justify-content: center; }
.contact p {
  color: var(--ink-mid);
  font-style: italic;
  margin: 0 0 2rem;
}
.contact .btn { margin-bottom: 1rem; }

.site-footer {
  position: relative;
  z-index: 1;
  border-top: 1px solid var(--hairline);
  padding: 1.5rem 0;
  color: var(--ink-dim);
  text-align: center;
}

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

/* ── Responsive ─────────────────────────────────────────────────────── */

/* Tablet: tighten spacing, keep the full nav row (still fits) */
@media (max-width: 900px) {
  .hero { padding: 6rem 1.75rem 5rem; }
  .nav-right { gap: 1rem; }
}

/* Phone/small tablet: collapse project cards to one column, switch nav
   to a hamburger-triggered dropdown */
@media (max-width: 760px) {
  .project-card { grid-template-columns: 1fr; gap: 1.5rem; }
  .project-card.reverse .project-visual { order: 0; }
  .project-visual { min-height: 200px; }

  .container { padding: 0 1.25rem; }
  /* .hero carries both .container and .hero — .container's padding reset
     above would otherwise win (same specificity, later in source) and
     zero out the vertical padding that creates the gap below the header;
     this has to come after it to take effect. */
  .hero { padding: 3.25rem 1.25rem 3.5rem; }

  /* Baseline alignment is the right call on desktop, where every nav item is
     text. Here the hamburger joins the row and has no text, so its baseline
     is synthesized from its bottom edge — aligning the logo and toggle to
     that leaves them sitting high. Center the boxes instead. */
  .nav {
    align-items: center;
    padding: 0.9rem 1.25rem;
  }

  .nav-toggle { display: flex; }

  .nav-right {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--paper);
    border-bottom: 1px solid var(--hairline);
    max-height: 0;
    overflow: hidden;
    visibility: hidden;
    transition: max-height var(--dur) var(--ease);
  }
  .nav-right.is-open {
    max-height: 20rem;
    visibility: visible;
  }
  .nav-right a {
    padding: 1rem 1.25rem;
    min-height: 44px;
    display: flex;
    align-items: center;
    border-top: 1px solid var(--hairline-faint);
  }

  .nav-toggle {
    width: 2.75rem;
    height: 2.75rem;
  }

  /* Standalone toggle sits in the top bar now, so give it the same
     touch-target height as the hamburger next to it. */
  .theme-toggle {
    display: flex;
    align-items: center;
    min-height: 2.75rem;
  }

  section { padding: 2.75rem 1.25rem; }
  h2 { font-size: 1.6rem; }

  #work { margin-top: 1rem; }

  .resume-teaser {
    padding-top: 3rem;
    padding-bottom: 3rem;
  }
  .contact {
    padding-top: 3rem;
    padding-bottom: 3.5rem;
  }

  .resume-pillars { grid-template-columns: 1fr; }
}

/* Small phones */
@media (max-width: 420px) {
  .hero-actions { flex-direction: column; align-items: stretch; }
  .hero-actions .btn { text-align: center; }
}

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