/* CREATMOSPHERE — shared stylesheet
   Design tokens, identity-system elements (reel index, timecode),
   motion, and everything Tailwind's utility classes can't express cleanly. */

:root {
  --red-deep: #3D0401;
  --red-accent: #7A0A08;
  --red-ui: #D4483C; /* 4.6:1 on charcoal — passes WCAG AA for small text */
  --charcoal: #0A0706;
  --charcoal-raised: #150F0E;
  --text: #F5F5F0;
  --text-muted: #8A8880;
  --text-dim: #4A4944;
  --hairline: rgba(245, 245, 240, 0.12);
  --hairline-soft: rgba(245, 245, 240, 0.08);

  /* One motion language for the whole site: slow-out, like a film fade. */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-soft: cubic-bezier(0.4, 0, 0.2, 1);
  --t-fast: 0.35s;
  --t-med: 0.6s;
  --t-slow: 1s;
}

html {
  scroll-behavior: smooth;
}

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

body {
  background:
    radial-gradient(45% 35% at 94% 90%, rgba(122, 10, 8, 0.22) 0%, transparent 70%),
    radial-gradient(100% 80% at 8% -10%, var(--red-deep) 0%, var(--charcoal) 38%);
  background-attachment: fixed, fixed;
  color: var(--text);
  font-family: 'Inter', sans-serif;
  position: relative;
  transition: opacity 0.45s var(--ease-soft);
}

/* Page-to-page fade, driven by anim.js: the page fades in on load and
   fades out when an internal link is clicked. (CSS @view-transition was
   tried and dropped — Chromium sometimes left the hero image unpainted.) */
body.page-entering { opacity: 0; }
body.page-entered  { opacity: 1; }
body.page-leaving  { opacity: 0; transition-duration: 0.3s; pointer-events: none; }

/* Typesetting: headlines break into even lines, paragraphs avoid leaving a
   single word on the last line. Matters most for centered text. */
h1, h2, h3, .font-display {
  text-wrap: balance;
}
p, li, dd {
  text-wrap: pretty;
}

/* Scroll-reveal — uses the `translate` property (not `transform`) so it
   never fights with hover transforms on the same element. --d staggers
   items in a row (set by anim.js). */
.reveal {
  opacity: 0;
  translate: 0 24px;
  transition:
    opacity 0.9s var(--ease) var(--d, 0s),
    translate 1s var(--ease) var(--d, 0s);
}
.reveal.revealed {
  opacity: 1;
  translate: 0 0;
}

/* Text set in the red-ui accent gets a touch more weight to stay readable */
.text-red-ui {
  font-weight: 500;
}

/* Film grain overlay — SVG turbulence noise, no image asset needed */
body::before {
  content: "";
  position: fixed;
  inset: -60px;
  z-index: 60;
  pointer-events: none;
  opacity: 0.12;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}

@media (prefers-reduced-motion: no-preference) {
  body::before {
    animation: grain-shift 0.5s steps(4) infinite;
  }
}

@keyframes grain-shift {
  0%   { transform: translate(0, 0); }
  25%  { transform: translate(-2%, 2%); }
  50%  { transform: translate(2%, -2%); }
  75%  { transform: translate(-1%, 1%); }
  100% { transform: translate(0, 0); }
}

/* Vignette + a few fixed dust specks — like dust sitting on a film gate */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 61;
  pointer-events: none;
  background:
    radial-gradient(2px 2px at 18% 28%, rgba(245, 245, 240, 0.3) 0%, transparent 100%),
    radial-gradient(1.5px 1.5px at 76% 14%, rgba(245, 245, 240, 0.22) 0%, transparent 100%),
    radial-gradient(2px 2px at 62% 82%, rgba(245, 245, 240, 0.2) 0%, transparent 100%),
    radial-gradient(1.5px 1.5px at 9% 68%, rgba(245, 245, 240, 0.22) 0%, transparent 100%),
    radial-gradient(2px 2px at 91% 58%, rgba(245, 245, 240, 0.16) 0%, transparent 100%),
    radial-gradient(1.5px 1.5px at 40% 45%, rgba(245, 245, 240, 0.14) 0%, transparent 100%),
    radial-gradient(140% 140% at 50% 50%, transparent 55%, rgba(0, 0, 0, 0.5) 100%);
}

.font-display {
  font-family: 'Space Grotesk', sans-serif;
}

.tabular-nums {
  font-variant-numeric: tabular-nums;
}

/* Reel index nav labels: default white, active/dimmed states override.
   A hairline draws in underneath on hover, from the left like a wipe. */
.reel-index {
  position: relative;
  color: var(--text);
  transition: color var(--t-fast) var(--ease-soft);
  letter-spacing: 0.04em;
}
.reel-index::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -4px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.5s var(--ease);
}
.reel-index:hover::after,
.reel-index:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left;
}

.reel-index.is-active {
  color: var(--red-ui);
}

.reel-index.is-dimmed {
  color: var(--text-dim);
}

/* CTA arrows: caps text + arrow, no brackets, per identity system */
.cta {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  letter-spacing: 0.06em;
  font-weight: 500;
  color: var(--text);
  transition:
    gap 0.45s var(--ease),
    color var(--t-fast) var(--ease-soft),
    transform 0.2s var(--ease-soft);
}

.cta:hover {
  gap: 0.85rem;
  color: var(--red-ui);
}

.cta:active {
  transform: scale(0.97);
}

/* Inline text links (e.g. Instagram handles inside a paragraph): the
   underline brightens and thickens instead of just changing color. */
.link-underline {
  text-decoration: underline;
  text-decoration-color: rgba(245, 245, 240, 0.25);
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  transition:
    color var(--t-fast) var(--ease-soft),
    text-decoration-color var(--t-fast) var(--ease-soft),
    text-underline-offset var(--t-fast) var(--ease);
}
.link-underline:hover {
  color: var(--red-ui);
  text-decoration-color: currentColor;
  text-underline-offset: 6px;
}
.link-fade {
  transition: color var(--t-fast) var(--ease-soft);
}
.link-fade:hover {
  color: var(--red-ui);
}

/* Left-aligned, justified text (Contact page). Hyphenation uses the page's
   lang attribute, so justified lines don't open up big gaps. */
.justify-text {
  text-align: justify;
  hyphens: auto;
  -webkit-hyphens: auto;
  text-wrap: pretty;
}

/* Focus states — keyboard accessibility, kept visible */
a:focus-visible,
button:focus-visible {
  outline: 1px solid var(--red-ui);
  outline-offset: 3px;
}

/* Mobile nav — full-screen overlay. visibility (not just opacity) so the
   closed menu's links can't be reached with Tab or read by screen readers.
   Links rise in one after another when it opens. */
#mobile-nav {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.45s var(--ease-soft), visibility 0s linear 0.45s;
}

#mobile-nav.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity 0.45s var(--ease-soft), visibility 0s linear 0s;
}

#mobile-nav > * {
  opacity: 0;
  translate: 0 14px;
  transition: opacity 0.4s var(--ease-soft), translate 0.6s var(--ease);
}
#mobile-nav.is-open > * {
  opacity: 1;
  translate: 0 0;
}
#mobile-nav.is-open > :nth-child(1) { transition-delay: 0.08s; }
#mobile-nav.is-open > :nth-child(2) { transition-delay: 0.14s; }
#mobile-nav.is-open > :nth-child(3) { transition-delay: 0.2s; }
#mobile-nav.is-open > :nth-child(4) { transition-delay: 0.26s; }
#mobile-nav.is-open > :nth-child(5) { transition-delay: 0.32s; }
#mobile-nav.is-open > :nth-child(6) { transition-delay: 0.4s; }

/* Hamburger -> X, two lines that rotate into a cross */
.menu-line {
  display: block;
  width: 22px;
  height: 1.5px;
  background: var(--text);
  transition: transform 0.45s var(--ease);
}

.menu-line + .menu-line {
  margin-top: 6px;
}

#menu-btn.is-open .menu-line:first-child {
  transform: translateY(3.75px) rotate(45deg);
}

#menu-btn.is-open .menu-line:last-child {
  transform: translateY(-3.75px) rotate(-45deg);
}

/* Consistent depth on every portfolio/project card */
.card-shadow {
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
}

/* Project card: lifts a little, warms to deep red, and the cover drifts
   in slowly — like a dolly push. Pressing it settles back down. */
.card {
  transition:
    background-color var(--t-med) var(--ease-soft),
    box-shadow var(--t-med) var(--ease),
    transform var(--t-med) var(--ease);
}
.card.reveal {
  transition:
    opacity 0.9s var(--ease) var(--d, 0s),
    translate 1s var(--ease) var(--d, 0s),
    background-color var(--t-med) var(--ease-soft),
    box-shadow var(--t-med) var(--ease),
    transform var(--t-med) var(--ease);
}
.card:hover {
  background-color: var(--red-deep);
  box-shadow: 0 28px 56px rgba(0, 0, 0, 0.55);
  transform: translateY(-4px);
}
.card:active {
  transform: translateY(-1px) scale(0.99);
  transition-duration: 0.15s;
}
.card-media {
  transition: transform 1.4s var(--ease), opacity 0.8s var(--ease-soft);
}
.card:hover .card-media {
  transform: scale(1.04);
}

/* Title only until hover; the project detail fades up under it. Touch
   screens can't hover, so there the detail is simply always shown. */
@media (hover: hover) and (pointer: fine) {
  .card-meta {
    opacity: 0;
    translate: 0 6px;
    transition: opacity 0.45s var(--ease-soft), translate 0.6s var(--ease);
  }
  .card:hover .card-meta,
  .card:focus-visible .card-meta {
    opacity: 1;
    translate: 0 0;
  }
}

/* Lazy images fade in once loaded instead of popping in (main.js). */
.fade-img {
  opacity: 0;
}
.fade-img.is-loaded {
  opacity: 1;
}

/* Contact rows: the whole row is the link. On hover the value turns red
   and the arrow slides out a little. */
.contact-row {
  transition: background-color var(--t-med) var(--ease-soft), padding var(--t-med) var(--ease);
}
.contact-value {
  transition: color var(--t-fast) var(--ease-soft);
}
.contact-arrow {
  transition: transform 0.5s var(--ease), color var(--t-fast) var(--ease-soft);
}
.contact-row:hover .contact-value,
.contact-row:focus-visible .contact-value {
  color: var(--red-ui);
}
.contact-row:hover .contact-arrow,
.contact-row:focus-visible .contact-arrow {
  color: var(--red-ui);
  transform: translateX(6px);
}
@media (hover: hover) and (pointer: fine) {
  .contact-row:hover {
    background-color: rgba(245, 245, 240, 0.025);
    padding-left: 0.75rem;
    padding-right: 0.75rem;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .scroll-hint-arrow {
    animation: scroll-hint-bounce 2s ease-in-out infinite;
  }
}
@keyframes scroll-hint-bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(5px); }
}

/* Video poster + play button shown until YouTube loads (js/yt-player.js) */
.yt-facade:focus-visible {
  outline: 1px solid var(--red-ui);
  outline-offset: -4px;
}
.yt-facade img {
  transition: transform 1.4s var(--ease);
}
.yt-facade:hover img {
  transform: scale(1.02);
}
.yt-facade:active .yt-play {
  scale: 0.94;
}
.yt-play {
  transition: background-color var(--t-med) var(--ease-soft), scale 0.5s var(--ease);
}
.yt-facade:hover .yt-play {
  scale: 1.08;
}

@media (prefers-reduced-motion: no-preference) {
  .yt-facade.is-loading .yt-play {
    animation: yt-loading 1s ease-in-out infinite;
  }
}
@keyframes yt-loading {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

/* Still-frame marquee — motion driven by JS (main.js) for smooth hover-slowdown.
   This just sets the track to its natural content width so JS can measure/scroll it. */
.marquee-track {
  width: max-content;
  will-change: transform;
}

/* Soft edge fade so frames don't hard-clip at the viewport edge */
.marquee-mask {
  -webkit-mask-image: linear-gradient(to right, transparent 0%, black 6%, black 94%, transparent 100%);
  mask-image: linear-gradient(to right, transparent 0%, black 6%, black 94%, transparent 100%);
}

/* Portrait stills are narrower per-image, so the same 6% fade eats too far
   into each frame — use a tighter fade so it reads as an edge softener,
   not a blur over the image itself. */
.marquee-mask-tight {
  -webkit-mask-image: linear-gradient(to right, transparent 0%, black 2.5%, black 97.5%, transparent 100%);
  mask-image: linear-gradient(to right, transparent 0%, black 2.5%, black 97.5%, transparent 100%);
}

/* FAQ (For Business page): native <details>, so it works without JS and
   with keyboards/screen readers. Browsers that support animating to
   height:auto open it smoothly; others just open instantly. */
.faq-item {
  border-bottom: 1px solid var(--hairline);
  interpolate-size: allow-keywords;
}
.faq-item summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.5rem 0;
  transition: color var(--t-fast) var(--ease-soft);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { color: var(--red-ui); }
.faq-icon {
  flex-shrink: 0;
  width: 14px;
  height: 14px;
  margin-top: 0.4rem;
  position: relative;
  transition: transform 0.5s var(--ease);
}
.faq-icon::before,
.faq-icon::after {
  content: "";
  position: absolute;
  inset: 50% 0 auto 0;
  height: 1.5px;
  background: currentColor;
  translate: 0 -50%;
}
.faq-icon::after { rotate: 90deg; }
.faq-item[open] .faq-icon { transform: rotate(45deg); }
.faq-item::details-content {
  block-size: 0;
  overflow: hidden;
  transition: block-size 0.55s var(--ease), content-visibility 0.55s allow-discrete;
}
.faq-item[open]::details-content {
  block-size: auto;
}
.faq-answer {
  padding-bottom: 1.6rem;
  opacity: 0;
  translate: 0 -6px;
  transition: opacity 0.5s var(--ease-soft) 0.05s, translate 0.6s var(--ease);
}
.faq-item[open] .faq-answer {
  opacity: 1;
  translate: 0 0;
}

/* Process steps: the number warms to red when you hover the step. */
.step-num {
  transition: color var(--t-fast) var(--ease-soft);
}
.step:hover .step-num {
  color: var(--red-ui);
}

/* Project form (Contact page): quiet underline fields that match the
   site's hairlines; the line warms to red while you type. */
.field {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.field-label {
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.field-hint {
  text-transform: none;
  letter-spacing: 0;
  color: var(--text-dim);
  margin-left: 0.35rem;
}
.field input,
.field select,
.field textarea {
  width: 100%;
  background: transparent;
  color: var(--text);
  border: 0;
  border-bottom: 1px solid var(--hairline);
  border-radius: 0;
  padding: 0.55rem 0;
  font-size: 1rem;
  font-family: 'Inter', sans-serif;
  transition: border-color var(--t-fast) var(--ease-soft);
  -webkit-appearance: none;
  appearance: none;
}
.field textarea {
  resize: vertical;
  min-height: 6rem;
  line-height: 1.6;
}
.field input::placeholder,
.field textarea::placeholder {
  color: var(--text-dim);
}
.field select {
  cursor: pointer;
  padding-right: 1.5rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238A8880' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.1rem center;
}
.field select:invalid {
  color: var(--text-dim);
}
.field select option {
  background: var(--charcoal-raised);
  color: var(--text);
}
.field input:hover,
.field select:hover,
.field textarea:hover {
  border-bottom-color: rgba(245, 245, 240, 0.3);
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-bottom-color: var(--red-ui);
}
.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  box-shadow: 0 1px 0 0 var(--red-ui);
}

.form-submit {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.85rem 1.4rem;
  border: 1px solid rgba(245, 245, 240, 0.25);
  border-radius: 999px;
  font-size: 0.875rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--text);
  background: transparent;
  cursor: pointer;
  transition:
    background-color var(--t-med) var(--ease-soft),
    border-color var(--t-med) var(--ease-soft),
    gap 0.45s var(--ease),
    transform 0.2s var(--ease-soft);
}
.form-submit:hover {
  background-color: var(--red-deep);
  border-color: var(--red-ui);
  gap: 0.9rem;
}
.form-submit:active {
  transform: scale(0.97);
}

/* About profile card (links to Instagram): the photo drifts in slowly on
   hover and the short description fades up under the name. The bottom fade
   deepens with it so the red text always stays readable. Touch screens show
   the description all the time. */
.profile-img {
  transition: transform 1.4s var(--ease);
}
.profile-card:hover .profile-img {
  transform: scale(1.04);
}
.profile-fade {
  background: linear-gradient(to top, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.6) 26%, rgba(0, 0, 0, 0) 58%);
}
@media (hover: hover) and (pointer: fine) {
  .profile-fade {
    background: linear-gradient(to top, rgba(0, 0, 0, 0.72) 0%, rgba(0, 0, 0, 0.25) 22%, rgba(0, 0, 0, 0) 45%);
    transition: opacity 0.6s var(--ease-soft);
  }
  .profile-fade::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.6) 30%, rgba(0, 0, 0, 0) 62%);
    opacity: 0;
    transition: opacity 0.6s var(--ease-soft);
  }
  .profile-card:hover .profile-fade::after,
  .profile-card:focus-visible .profile-fade::after {
    opacity: 1;
  }
  .profile-meta {
    opacity: 0;
    translate: 0 6px;
    transition: opacity 0.45s var(--ease-soft), translate 0.6s var(--ease);
  }
  .profile-card:hover .profile-meta,
  .profile-card:focus-visible .profile-meta {
    opacity: 1;
    translate: 0 0;
  }
}
