/* Carlos Flores — quiet frame, the photographs first. */

@font-face {
  font-family: 'LT Cushion';
  src: url('/assets/fonts/LTCushion-VF.ttf') format('truetype');
  font-weight: 300 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --paper: #f3f3f3;
  --ink: #272624;
  --stone: #655b45;   /* accents: current item, links */
  --khaki: #9f937e;   /* About */
  --olive: #717f68;   /* Contact */
  --neptune: #272640; /* the Neptunian page's panel */
  --neptune-deep: #222139; /* the Neptunian page beside its panel */
  --muted: color-mix(in srgb, var(--ink) 62%, var(--paper));

  --panel: clamp(220px, 17vw, 270px);
  --gutter: 16px;
  --space: clamp(24px, 3vw, 40px);
  --font: 'LT Cushion', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);

  /* Photos still loading (site-kit placeholders) when they have no dominant colour of their own. */
  --kit-placeholder: color-mix(in srgb, var(--ink) 6%, var(--paper));

  --photo-stroke: 6px; /* the hover stroke on a photo you can open (work covers, project photos) */

  /* The photo viewer (site-kit gallery): the page colour, with ink controls. */
  --gallery-bg: var(--paper);
  --gallery-icon-color: var(--ink);
  --gallery-icon-color-secondary: var(--paper);
  --gallery-icon-stroke-color: var(--paper);

  color-scheme: light;
}

@media (min-width: 900px) {
  :root { --gutter: var(--space); }
}

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 17px/1.5 var(--font);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

html.has-overlay { overflow: hidden; }

img { display: block; max-width: 100%; height: auto; }
picture { display: block; }
figure { margin: 0; }

a { color: inherit; text-decoration: none; }
/* Hover and the current page are underlined (it never shifts layout). Keyboard focus shows its
   outline. Cards and the pager underline just their title, not the whole link. */
a:hover,
.nav a[aria-current],
.card:hover .card-title,
.pager a:hover .pager-title,
.splash:hover .splash-enter,
.contact-form button:hover,
.gate-form button:hover {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
}
/* Icon buttons are links underneath; they shouldn't drag out as links (Safari needs the CSS too). */
.back, .overlay-close { -webkit-user-drag: none; user-select: none; }
/* Header icons: the back arrow and the X are one size everywhere. */
.back svg, .overlay-close svg { width: var(--head-icon, 24px); height: var(--head-icon, 24px); }
.card:hover, .pager a:hover, .back:hover, .gate-button:hover, .overlay-close:hover, .social-icon:hover { text-decoration: none; }
:focus-visible { outline: 1px solid currentColor; outline-offset: 3px; }

h1, h2, h3, p, ul, dl, dd { margin: 0; }
h1, h2 { font-size: inherit; font-weight: 400; }
ul { padding: 0; list-style: none; }

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

/* ── Text ──────────────────────────────────────────────────────────────── */

.prose { max-width: 36em; }
.prose p + p { margin-top: 1em; }
.prose h2 { margin-bottom: 0.5em; color: var(--muted); }
.prose a { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.2em; }

/* ── Frame: the panel and the main column ───────────────────────────────── */

.panel {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--paper);
}

.panel-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 56px;
  padding: 0 var(--gutter);
}

.brand { font-size: 22px; letter-spacing: 0.01em; }
.brand-logo img { width: auto; max-height: 28px; }

.menu-toggle { display: inline-flex; padding: 10px 0 10px 16px; margin-right: -2px; -webkit-user-drag: none; }
.menu-toggle svg { width: 24px; height: 24px; display: block; }
.menu-toggle:hover { text-decoration: none; }
.menu-toggle .menu-close,
.panel[data-open] .menu-toggle .menu-open,
.panel:target .menu-toggle .menu-open { display: none; }
.panel[data-open] .menu-toggle .menu-close,
.panel:target .menu-toggle .menu-close { display: inline-flex; }

.nav { display: none; }
.panel[data-open] .nav,
.panel:target .nav {
  display: flex;
  flex-direction: column;
  height: calc(100svh - 56px);
  overflow-y: auto;
  padding: 8px var(--gutter) 24px;
  font-size: 28px;
  line-height: 1.35;
  text-align: right; /* phones: options line up under the hamburger */
}

/* Each link is a full row: its target runs the width of the panel, and the rows meet with no gap
   between them (the spacing is the links' own padding). */
.nav-list { margin: -0.175em 0; }
.nav-list a { display: block; padding: 0.175em 0; }
.nav a[aria-current] { color: var(--stone); }

/* The project layout switch, at the foot of the panel (phones: the foot of the menu, at the right
   like the links). Two square cells in a thin frame; a solid square slides under the chosen one. */
.layout-switch { position: relative; display: inline-flex; align-self: flex-end; margin-top: auto; border: 1px solid var(--ink); }
.layout-switch[hidden] { display: none; }
.layout-switch::before { content: ''; position: absolute; inset: 0 auto 0 0; width: 40px; background: var(--stone); transition: translate 0.3s var(--ease); } /* the chosen layout, in the current-page colour; one button wide */
.layout-switch:has(> button:last-child[aria-pressed='true'])::before { translate: 100% 0; }
.layout-switch button { position: relative; display: grid; place-items: center; width: 40px; height: 40px; padding: 0; border: 0; background: none; color: var(--ink); cursor: pointer; transition: color 0.3s var(--ease); }
.layout-switch button[aria-pressed='true'] { color: var(--paper); }
.layout-switch svg { display: block; width: 20px; height: 20px; }

.gate-button { display: inline-block; width: 56px; }
.gate-button img { aspect-ratio: 1; object-fit: contain; } /* round on its own */

.main { padding: 0 0 64px; outline: none; }

@media (min-width: 900px) {
  .shell { display: grid; grid-template-columns: var(--panel) minmax(0, 1fr); }

  .panel {
    height: 100vh;
    display: flex;
    flex-direction: column;
    padding: var(--space) 0 var(--space) var(--space);
  }
  .panel-bar { display: block; min-height: 0; padding: 0; }
  .brand { display: block; } /* the name's target runs the width of the panel too */
  .menu-toggle { display: none; }

  .nav,
  .panel[data-open] .nav,
  .panel:target .nav {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    height: auto;
    margin-top: 48px;
    padding: 0;
    overflow-y: auto;
    font-size: 20px;
    text-align: left;
  }

  :root { --head-icon: 32px; } /* desktop header icons; phones keep 24px to match the hamburger */
  .main { padding: var(--space) var(--space) 96px; }
}

/* ── Work ──────────────────────────────────────────────────────────────── */

.work-intro { padding: 8px var(--gutter) 32px; }

/* The projects as square covers, two to a row at every size, like a project's grid: edge to edge
   with an 8px gap on phones, var(--space) between them on desktop. Each cover is cut around its
   focal point (the centre unless one is set). */
.work-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px 8px; }

.card { display: block; }
.card-media { position: relative; display: block; aspect-ratio: 1; background: color-mix(in srgb, var(--ink) 6%, var(--paper)); overflow: hidden; }
.card-media picture, .card-media img { width: 100%; height: 100%; }
.card-media img { object-fit: cover; }

/* A photo you can open, here or on a project, draws a stroke in the current-page colour in from its
   edges on hover (and on keyboard focus, in place of the outline). One set of rules for both, so a
   cover and a project's photo always behave the same. */
:is(.frame-link, .card-media)::after { content: ''; position: absolute; inset: 0; box-shadow: inset 0 0 0 0 var(--stone); transition: box-shadow 0.35s var(--ease); pointer-events: none; }
@media (hover: hover) {
  .frame-link:hover::after, .card:hover .card-media::after { box-shadow: inset 0 0 0 var(--photo-stroke) var(--stone); }
}
:is(.frame-link, .card):focus-visible { outline: none; }
.frame-link:focus-visible::after, .card:focus-visible .card-media::after { box-shadow: inset 0 0 0 var(--photo-stroke) var(--stone); }
.card-title { display: block; margin-top: 10px; padding: 0 var(--gutter); }
.card-meta { display: block; padding: 0 var(--gutter); color: var(--muted); font-size: 15px; }

@media (min-width: 900px) {
  .work-intro { padding: 0 0 var(--space); }
  .work-grid { gap: 56px var(--space); }
  .card-title, .card-meta { padding: 0; }
}

/* The work's two views, from the switch in the panel: Projects (the default) and Shuffle. Without the
   script, the list of projects. */
.work-gallery, .work-shuffle { display: none; }
/* Until site.js has placed the photos they're out of sight (head.js sets is-placing before the first
   paint, so nothing shows in the wrong place), then they fade in. */
:is(.main--project .chapter > .frame, .work-gallery, .work-shuffle, .secret-section > .frame) { transition: opacity 0.4s var(--ease); }
:root.is-placing :is(.main--project .chapter > .frame, .work-gallery, .work-shuffle, .secret-section > .frame) { opacity: 0; }
:root[data-work='projects'] .work-gallery, :root[data-work='shuffle'] .work-shuffle { display: block; }
:root[data-work] .work-grid { display: none; }
/* Projects: a project's first photos in one row at one height (site.js sets each one's share of the
   row from its shape), at most five; three on phones, so they stay a good size. */
.work-row { display: flex; align-items: flex-start; gap: 8px; }
.work-row > .frame { flex: 1 1 0; min-width: 0; margin: 0; }
.work-row > .frame + .frame { margin-top: 0; } /* not the stacked photos' gap, which comes later */
.work-row figcaption { display: none; }
@media (max-width: 899px) { .work-row > .frame:nth-child(n + 4) { display: none; } }
/* The title leads to the project, with a right chevron that nudges on hover (Back's, mirrored). */
.work-project { display: inline-flex; align-items: center; gap: 0.35em; }
.work-project .chevron { flex: none; width: 0.32em; height: 0.96em; translate: 0 -0.06em; transition: transform 0.3s var(--ease); }
.work-project:hover .chevron, .work-project:focus-visible .chevron { transform: translateX(3px); }
/* Each project's title a step up from the text (a project page's title size on desktop), close
   over its photos, and a shorter gap from one project's photos to the next title than between a project's chapters. */
.work-gallery .chapter-text { padding-bottom: 12px; } /* the title sits close over its own photos */
.work-gallery .chapter-text h2 { font-size: 22px; line-height: 1.25; }
.work-gallery .chapter + .chapter { margin-top: 40px; }
@media (min-width: 900px) {
  .work-gallery .chapter-text { padding-bottom: 16px; }
  .work-row { gap: var(--space); }
  .work-gallery .chapter-text h2 { font-size: 25px; }
  .work-gallery .chapter + .chapter { margin-top: 64px; }
}

/* ── Project ───────────────────────────────────────────────────────────── */

.project-head {
  display: grid;
  grid-template-columns: minmax(0, 36em);
  align-items: start;
  row-gap: 12px;
  padding: 8px var(--gutter) 32px;
}
.project-title { font-size: 25px; line-height: 1.25; }
/* Back: the arrow and the word. Phones: on its own line above the title. */
.back { display: inline-flex; align-items: center; gap: 0.3em; justify-self: start; color: var(--ink); transition: color 0.2s var(--ease); }
.back svg.chevron { flex: none; width: calc(var(--head-icon, 24px) / 3); translate: 0 -0.09em; transition: transform 0.3s var(--ease); } /* a third as wide as tall; raised to the capitals' middle */
.back:hover, .back:focus-visible { color: var(--stone); }
.back:hover .chevron, .back:focus-visible .chevron { transform: translateX(-3px); }
.project-meta { color: var(--muted); }
.project-bio { margin-top: 1.25em; }

.chapter + .chapter { margin-top: 56px; }
.chapter-text { padding: 0 var(--gutter) 24px; }

/* Phones: every photograph runs edge to edge. */
.frame + .frame { margin-top: 8px; }
.frame img { width: 100%; }
/* Each photo opens the viewer; its hover stroke is shared with the work's covers (see Work). */
.frame-link { position: relative; display: block; }
figcaption { padding: 8px var(--gutter) 0; color: var(--muted); font-size: 15px; }

.credits { display: grid; gap: 4px; margin-top: 56px; padding: 0 var(--gutter); font-size: 15px; }
.credits div { display: flex; gap: 0.5em; }
.credits dt { color: var(--muted); }
.credits dt::after { content: ':'; }

.pager {
  display: flex;
  justify-content: space-between;
  gap: 24px;
  margin-top: 64px;
  padding: 0 var(--gutter);
}
.pager a { max-width: 45%; }
.pager a[rel='next'] { text-align: right; }
.pager-label { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: 15px; }
.pager a[rel='next'] .pager-label { justify-content: flex-end; }
.pager .arrow { width: 18px; height: 18px; transition: transform 0.3s var(--ease); }
.pager a:hover .arrow--left, .pager a:focus-visible .arrow--left { transform: translateX(-3px); }
.pager a:hover .arrow--right, .pager a:focus-visible .arrow--right { transform: translateX(3px); }

/* Tiles (a project's, the work's and the Neptunian page's): equal columns, two on phones and four on desktop, each
   photo its own shape, uncropped, with the same gap across and down. CSS sets the columns' width;
   site.js places each photo under the shortest column so far, like a masonry wall. */
:is(:root[data-layout="tiles"] .main--project .chapter, :root[data-work="shuffle"] .work-shuffle .chapter, :root[data-personal="tiles"] .secret-section) { --tile-columns: 2; --tile-gap: 8px; position: relative; }
:is(:root[data-layout="tiles"] .main--project, :root[data-work="shuffle"] .work-shuffle, :root[data-personal="tiles"] .secret-main) .frame { position: absolute; width: calc((100% - (var(--tile-columns) - 1) * var(--tile-gap)) / var(--tile-columns)); margin-top: 0; }
:is(:root[data-layout="tiles"] .main--project, :root[data-work="shuffle"] .work-shuffle, :root[data-personal="tiles"] .secret-main) figcaption { display: none; }

@media (min-width: 900px) {
  /* Desktop: the title starts at the photos' left edge; Back sits at the right edge of the page, set
     like the title so the two share a line, and stays there as the project scrolls (under the panel
     and overlays). */
  .project-head { padding: 0 0 var(--space); }
  /* One title line tall, so the word sits on the title's line. The padding is taken back out of top
     and right, so the word stays where it was and only the box around it reaches further. */
  /* 4px at the bottom, not 8px: the line keeps room under the baseline for descenders, and "Back" has
     none, so even padding left the word sitting high with more space below it than above. */
  .project-head .back { position: fixed; top: calc(var(--space) - 8px); right: calc(var(--space) - 12px); z-index: 10; box-sizing: content-box; height: 1.25em; margin-left: 0; padding: 8px 12px 4px; font-size: 25px; line-height: 1.25; background-color: var(--paper); transition: color 0.2s var(--ease); }
  /* Photos pass under Back as the project scrolls, so it sits on a square of the page colour. */
  .project-intro > * { max-width: 36em; }
  .chapter-text { padding: 0 0 var(--space); }
  .chapter + .chapter { margin-top: 96px; }

  /* Desktop: every photograph the full column width, whatever its shape; vertical ones run taller
     than the window and scroll through. */
  .frame + .frame { margin-top: var(--space); }
  .frame img { width: 100%; }
  figcaption { padding: 10px 0 0; }

  .credits, .pager { padding: 0; }
  .pager { margin-top: 96px; }

  .layout-switch { align-self: flex-start; }
  :is(:root[data-layout="tiles"] .main--project .chapter, :root[data-work="shuffle"] .work-shuffle .chapter, :root[data-personal="tiles"] .secret-section) { --tile-columns: 4; --tile-gap: var(--space); }
}

/* The viewer's controls (PhotoSwipe, themed through --gallery-* above), in ink at the size of an
   overlay's title and X: the count at the top left and the X at the top right, in a bar placed like
   the page's header (phones: the 56px bar; desktop: the title's line, var(--space) in from the
   edges), and on desktop the previous and next chevrons at the bottom left, placed as the count's
   mirror. */
.pswp--kit .pswp__top-bar { height: auto; min-height: 56px; align-items: center; padding: 0 var(--gutter); }
/* Each sits on a square of the page colour, like the pinned Back, so it reads over any photo. The
   room around the count and the X is taken back out of their margins, so they stay put. .pswp twice
   outranks PhotoSwipe's own .pswp__button:hover, which would otherwise clear the fill on hover. */
.pswp.pswp--kit :is(.pswp__counter, .pswp__button--close, .pswp__button--arrow) { background-color: var(--paper); }
/* Like Back: 4px below, not 8px, as the line keeps room for descenders the count doesn't have. */
.pswp--kit .pswp__counter { height: auto; padding: 8px 12px 4px; margin: -8px -12px -4px; color: var(--ink); text-shadow: none; opacity: 1; font-size: 22px; line-height: 1.25; }
/* The buttons' sizes come from width and height, never padding: PhotoSwipe zeroes a button's padding
   on hover and focus, which would shrink it out from under the pointer and make the cursor flicker.
   The X's box is as tall as the count's (1.25em + 12px). */
.pswp--kit :is(.pswp__button--close, .pswp__button--arrow) { display: grid; height: calc(1.25em + 12px); font-size: 22px; color: var(--ink); opacity: 1; }
.pswp--kit :is(.pswp__button--close, .pswp__button--arrow) svg { width: var(--head-icon, 24px); height: var(--head-icon, 24px); }
.pswp--kit :is(.pswp__button--close, .pswp__button--arrow):hover { color: var(--stone); }
.pswp--kit .pswp__button--close { place-items: center; width: calc(var(--head-icon, 24px) + 24px); margin: -4px -14px 0 auto; }
/* Phones swipe; the chevrons are for desktop only. */
.pswp--kit .pswp__button--arrow { display: none; }
@media (min-width: 900px) {
  .pswp--kit .pswp__top-bar { min-height: 0; align-items: flex-start; padding: var(--space) var(--space) 0; }
  .pswp--kit .pswp__counter { font-size: 25px; }
  .pswp--kit :is(.pswp__button--close, .pswp__button--arrow) { font-size: 25px; }
  .pswp--kit .pswp__button--close { margin: -8px calc(var(--head-icon) * -5.5 / 24 - 12px) 0 auto; }
  /* The two chevrons share one box, 88px wide (44px each, none between) and taller than the count's,
     with 40px chevrons. Its bottom sits as far from the bottom as the count's box top from the top.
     PhotoSwipe hides arrows on touch screens until a mouse is used; a wide touch screen shows them. */
  .pswp.pswp--kit .pswp__button--arrow { visibility: visible; }
  .pswp--kit .pswp__button--arrow { display: grid; top: auto; bottom: calc(var(--space) - 8px); width: 44px; height: calc(1.25em + 24px); margin: 0; }
  .pswp--kit .pswp__button--arrow svg { width: 40px; height: 40px; }
  .pswp--kit .pswp__button--arrow--prev { left: calc(var(--space) - 12px); place-items: center end; }
  .pswp--kit .pswp__button--arrow--next { left: calc(var(--space) + 32px); right: auto; place-items: center start; }
}

/* ── Overlays: About, Contact, other pages ─────────────────────────────── */

.overlay {
  position: fixed;
  inset: 0;
  z-index: 30;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 24px var(--gutter); /* same top and bottom: an overlay that fits doesn't scroll */
}
.overlay[hidden] { display: none; }
.overlay:focus { outline: none; } /* focused on open so screen readers land in it; not a control */

/* An overlay fades in on top of whatever is showing; site.js hides what's underneath once the
   fade ends. Above everything while entering, the login included. */
.overlay.is-entering { z-index: 50; animation: overlay-in 0.4s var(--ease) both; }

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

.overlay--about { background: var(--khaki); color: var(--ink); }
.overlay--page { background: var(--paper); color: var(--ink); }
/* The Neptunian page, behind the login: dark, so every bit of text on it is light (paper: 14:1). */
.overlay--secret { --stone: var(--paper); background: var(--neptune-deep); color: var(--paper); } /* light strokes on its photos */
/* The photo viewer opened from it (attached to the page's end, so set from the root): the page's
   deep blue with light controls, a dimmer light on hover. */
:root:has(.overlay--secret:not([hidden])) .pswp--kit {
  --paper: var(--neptune-deep);
  --ink: #f3f3f3;
  --stone: color-mix(in srgb, #f3f3f3 60%, var(--neptune-deep));
  --gallery-bg: var(--neptune-deep);
  --gallery-icon-color: #f3f3f3;
  --gallery-icon-color-secondary: var(--neptune-deep);
  --gallery-icon-stroke-color: var(--neptune-deep);
}
.overlay--secret a, .overlay--secret h2, .overlay--secret .overlay-title { color: var(--paper); }
/* Paper on olive is 3.8:1, so contact text stays large. */
.overlay--contact { background: var(--olive); color: var(--paper); font-size: 21px; }

/* The X and the title in their own columns (the X on the right on desktop and phones). */
.overlay-head {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  column-gap: 10px;
  align-items: center;
  margin-bottom: 32px;
}
/* LT Cushion's letters sit high in their line, so the X comes up 2px to centre on the capitals. */
.overlay-close { display: inline-flex; margin-left: -4px; padding: 2px 4px; translate: 0 -2px; color: inherit; opacity: 0.75; transition: opacity 0.2s var(--ease); }
.overlay-close:hover, .overlay-close:focus-visible { opacity: 1; }
/* Overlay headings match project titles, so every page header reads the same. */
.overlay-title { font-size: 25px; line-height: 1.25; }

.prose-section + .prose-section { margin-top: 48px; }
.prose-media { display: grid; gap: 16px; margin: 0 calc(-1 * var(--gutter)) 24px; }
.prose-media figcaption { padding: 8px var(--gutter) 0; color: inherit; opacity: 0.8; }
.overlay .prose h2 { color: inherit; font-size: 15px; letter-spacing: 0.04em; }
.overlay--about .prose { font-size: 19px; line-height: 1.55; }

.about-links { --about-icon: 44px; display: flex; align-items: center; gap: 20px; margin-top: 40px; }
.prose-column { display: flex; flex-direction: column; }
.social-icon { display: inline-flex; padding: 8px; margin-left: -8px; }
.social-icon svg { width: var(--about-icon); height: var(--about-icon); } /* same height as the Neptune image */
.about-gate { width: var(--about-icon); }
/* Instagram and Neptune share one hover: a slight grow. */
.about-links a svg, .about-links a img { transition: transform 0.3s var(--ease); }
.about-links a:hover svg, .about-links a:hover img,
.about-links a:focus-visible svg, .about-links a:focus-visible img { transform: scale(1.06); }

.contact-grid { display: grid; gap: 48px; }
.contact-details li + li { margin-top: 0.2em; }
.contact-details { font-size: clamp(25px, 2.7vw, 34px); line-height: 1.3; }
.contact-area { margin-top: 1em; }
.contact-grid .prose { margin-top: 1.5em; }
.contact-image { margin-top: 24px; max-width: 320px; }

.contact-form { display: grid; gap: 20px; max-width: 32em; }
.contact-form label { display: block; margin-bottom: 4px; }
.contact-form input,
.contact-form textarea,
.contact-form select {
  width: 100%;
  padding: 8px 0;
  border: 0;
  border-bottom: 1px solid currentColor;
  border-radius: 0;
  background: transparent;
  color: inherit;
  font: inherit;
}
.contact-form textarea { resize: vertical; height: clamp(5.5em, 24svh, 9em); } /* shorter on short windows */
/* Browser autofill paints its own light background, which hid the light text until edited. Cover it
   with the page colour and keep the text light. */
.contact-form :is(input, textarea, select):autofill,
.contact-form :is(input, textarea, select):-webkit-autofill {
  -webkit-text-fill-color: var(--paper);
  caret-color: var(--paper);
  box-shadow: inset 0 0 0 1000px var(--olive);
  transition: background-color 600000s 0s; /* Chrome keeps its own background otherwise */
}
.contact-form select option { color: var(--ink); }
.contact-form :focus-visible { outline: none; border-bottom-width: 2px; }
.contact-form button,
.gate-form button {
  justify-self: start;
  padding: 10px 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

@media (min-width: 900px) {
  /* The panel stays in view: overlays cover only the work. */
  .overlay { left: var(--panel); padding: var(--space); }
  /* Desktop: the title on the left, the X in its own column at the right. */
  .overlay-head { grid-template-columns: minmax(0, 1fr) max-content; column-gap: var(--space); margin-bottom: var(--space); }
  /* The X's visible end (x=18.5 of its 24-unit box) lands on the content's right edge. */
  .overlay-close { order: 2; padding-right: 0; margin-right: calc(var(--head-icon) * -5.5 / 24); }

  .prose-section.has-media { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: var(--space); align-items: stretch; }
  .prose-section.has-media .prose-media { align-self: start; }
  /* The photo never runs past the window, so About doesn't scroll: the window less the overlay's
     padding (top and bottom), the 36px title row, and the space under it. */
  .prose-section.has-media .prose-media img { width: auto; max-height: calc(100svh - 3 * var(--space) - 36px); }
  /* Beside a photo, the links sit at the bottom of the text column, level with the photo's foot. */
  .prose-section.has-media .about-links { margin-top: auto; padding-top: 40px; }
  .prose-media { margin: 0; }

  /* Contact's type grows with the window, so it doesn't sit small in a wide, empty overlay. */
  .overlay--contact { font-size: clamp(22px, 1.1vw + 10px, 30px); }
  .contact-details { font-size: clamp(30px, 3vw, 52px); }
  .contact-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space); }
}


/* Phones: the top bar stays, as on any page, and an overlay fills the screen under it. The hamburger
   moves between pages (Work closes the overlay), so there's no X, and the open menu drops over the
   overlay. The title heads the page like a project's, at the same size. The overlay runs to the
   bottom of the screen, under Safari's floating toolbar, so its end has room to scroll clear of it
   (Send, About's icons). */
@media (max-width: 899px) {
  .panel { z-index: 40; }
  .overlay { top: 56px; padding-top: 0; padding-bottom: calc(112px + env(safe-area-inset-bottom)); }
  .overlay-close { display: none; }
  .overlay-head { display: block; margin-bottom: 0; padding: 8px 0 24px; }
  /* LT Cushion's letters ride ~2px high, so the name comes down to meet the hamburger's centre. */
  .brand { translate: 0 2px; }
}

/* ── The Neptunian page: a takeover, with its own panel ────────────────── */

/* It covers everything, the site's panel included, and lays itself out the same way: its panel's
   name and links land exactly where the site's were. */
.overlay--takeover { padding: 0; }
@media (max-width: 899px) { .overlay--takeover { top: 0; z-index: 45; } }
.panel--secret { background: var(--neptune); color: var(--paper); }
.panel--secret .nav a[aria-current] { color: var(--paper); }
/* Log Out leads with a left chevron, sized and set like Back's; on hover it nudges left. */
.nav-list .nav-logout { display: flex; align-items: center; gap: 0.6em; } /* a full row like the other links, laid out as a row */
/* A little space between Log Out and the sections (a margin, so it isn't part of Log Out's target). */
.panel--secret .nav-list > li:has(> .nav-logout) { margin-bottom: 0.75em; }
.nav-logout .chevron { flex: none; width: 0.4267em; height: 1.28em; translate: 0 -0.09em; transition: transform 0.3s var(--ease); }
.nav-logout:hover .chevron, .nav-logout:focus-visible .chevron { transform: translateX(-3px); }
@media (max-width: 899px) { .nav-list .nav-logout { justify-content: flex-end; } } /* phones: the menu is right-aligned */
/* The link list scrolls if it's long, which also clips sideways: give it room on the left (into the
   panel's padding, so nothing moves) for the chevron's hover nudge. */
@media (min-width: 900px) { .panel--secret .nav { margin-left: -12px; padding-left: 12px; } }
.secret-view { padding: 16px 0 0; }
.secret-view[hidden] { display: none; }
.secret-view .overlay-title { margin-bottom: 24px; padding: 0 var(--gutter); translate: none; }
.secret-section .prose { padding: 0 var(--gutter) 24px; }
.secret-section + .secret-section { margin-top: 48px; }

@media (min-width: 900px) {
  .overlay--takeover { left: 0; padding: 0; }
  .overlay--takeover:not([hidden]) { display: grid; grid-template-columns: var(--panel) minmax(0, 1fr); align-items: start; }
  .secret-main { padding: var(--space) var(--space) 96px; }
  .secret-view { padding: 0; }
  .secret-view .overlay-title { margin-bottom: var(--space); padding: 0; }
  .secret-section .prose { max-width: 36em; padding: 0 0 var(--space); }
  .secret-section + .secret-section { margin-top: 96px; }
}

/* ── The Neptune gate ──────────────────────────────────────────────────── */

/* A normal overlay (beside the panel, same fade), in black, with the login centred in it. */
.overlay--gate { background: var(--ink); color: var(--paper); }
.gate { width: min(320px, 100%); margin: 6vh auto 0; text-align: center; }
.gate-image { width: 120px; margin: 0 auto 32px; }
.gate-image img { aspect-ratio: 1; object-fit: contain; }
.gate-text { margin-bottom: 24px; color: color-mix(in srgb, var(--paper) 70%, var(--ink)); }

.gate-form { display: grid; gap: 16px; text-align: left; }
.gate-form span { display: block; margin-bottom: 4px; font-size: 15px; color: color-mix(in srgb, var(--paper) 70%, var(--ink)); }
.gate-form input {
  width: 100%;
  padding: 8px 0;
  border: 0;
  border-bottom: 1px solid color-mix(in srgb, var(--paper) 40%, var(--ink));
  border-radius: 0;
  background: transparent;
  color: var(--paper);
  font: inherit;
  font-size: 18px;
}
.gate-form input:focus-visible { outline: none; border-bottom-color: var(--paper); }
.gate-form input:autofill,
.gate-form input:-webkit-autofill {
  -webkit-text-fill-color: var(--paper);
  caret-color: var(--paper);
  box-shadow: inset 0 0 0 1000px var(--ink);
  transition: background-color 600000s 0s;
}
.gate-form input[readonly] { color: color-mix(in srgb, var(--paper) 70%, var(--ink)); cursor: default; }
.gate-form button { justify-self: center; margin-top: 8px; transition: opacity 0.3s var(--ease), visibility 0.3s; }
/* Enter appears once something is typed in the password. */
.gate-form:has(input[name='password']:placeholder-shown) button { opacity: 0; visibility: hidden; }
/* The hint sits under Enter and shows even before Enter does (Enter keeps its space while hidden). */
.gate-hint { justify-self: center; margin-top: -8px; font-size: 13px; color: var(--paper); }


/* ── Landing page ──────────────────────────────────────────────────────── */

.splash { position: relative; height: 100svh; overflow: hidden; background: var(--ink); color: var(--paper); }

.splash-media, .splash-media picture { position: absolute; inset: 0; }
.splash-media img { width: 100%; height: 100%; object-fit: cover; }
.splash-media picture { opacity: 0; transition: opacity 1.6s var(--ease); }
.splash-media picture.is-active { opacity: 1; }
.splash-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgb(39 38 36 / 0.28);
}

/* Centered over the image. The Enter link stretches over the whole page, so a tap anywhere enters. */
.splash-content {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: var(--gutter);
  text-align: center;
}
.splash-name { font-size: 30px; letter-spacing: 0.01em; }
.splash-name img { width: auto; max-height: 48px; margin: 0 auto; }
.splash-text { max-width: 32em; opacity: 0.85; }
.splash-text a { position: relative; z-index: 1; text-decoration: underline; text-underline-offset: 0.2em; }
.splash-enter { font-size: 17px; letter-spacing: 0.06em; opacity: 0.85; transition: opacity 0.3s var(--ease); }
.splash-enter::after { content: ''; position: absolute; inset: 0; }
.splash:hover .splash-enter { opacity: 1; }
.splash-enter:focus-visible { outline: none; opacity: 1; text-decoration: underline; text-underline-offset: 0.3em; }

@media (min-width: 900px) {
  .splash-name { font-size: 38px; }
  .splash-enter { font-size: 18px; }
}

/* ── Not found ─────────────────────────────────────────────────────────── */

.missing { padding: 8px var(--gutter); }
.missing p { margin-top: 0.5em; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
