/*
 * Ham Chơi shared styling.
 * The map and about page intentionally share the same small visual language.
 */
:root {
  color-scheme: light;
  --paper: #f5f0e6;
  --paper-soft: #fbf8f0;
  --ink: #1e2929;
  --muted: #65706f;
  --hairline: rgba(30, 41, 41, 0.16);
  --hairline-strong: rgba(30, 41, 41, 0.28);
  --accent: #ef694f;
  --accent-deep: #bf4938;
  --panel: rgba(251, 248, 240, 0.97);
  --shadow: 0 18px 60px rgba(24, 36, 36, 0.16);
  --serif: Georgia, "Times New Roman", serif;
  --sans: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --paper: #1c2424;
  --paper-soft: #222c2b;
  --ink: #e9ece7;
  --muted: #a2aeaa;
  --hairline: rgba(233, 236, 231, 0.15);
  --hairline-strong: rgba(233, 236, 231, 0.3);
  --panel: rgba(28, 36, 36, 0.97);
  --shadow: 0 18px 60px rgba(0, 0, 0, 0.32);
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  min-height: 100%;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
}

button,
a {
  color: inherit;
  font: inherit;
}

a {
  text-decoration: none;
}

button {
  border: 0;
  cursor: pointer;
}

.map-page {
  overflow: hidden;
}

/* Globe intro: a full-screen sheet of paper the wireframe globe unrolls on,
   sitting above everything (lightbox is 1000) until it fades and removes
   itself. globe-intro.js keeps its FADE_MS in sync with the transition. */
.globe-intro {
  align-items: center;
  background: var(--paper);
  cursor: pointer;
  display: flex;
  inset: 0;
  justify-content: center;
  position: fixed;
  transition: opacity 650ms ease;
  z-index: 1200;
}

.globe-intro.is-done {
  opacity: 0;
  pointer-events: none;
}

/* The svg fills the whole viewport; globe-intro.js gives its viewBox the
   same shape, so the drawing is never letterboxed. dvh tracks the real
   visible height on phones, where browser chrome eats into 100vh. */
.globe-intro svg {
  height: 100vh;
  height: 100dvh;
  width: 100vw;
}

.globe-intro path {
  fill: none;
}

.globe-graticule {
  opacity: 0.7;
  stroke: var(--hairline);
}

/* Filled like the Leaflet basemap rather than a wireframe: warm-grey
   water, cream land, faint borders. The .globe-intro prefixes outrank the
   fill: none set on all paths above. */
.globe-intro .globe-sphere {
  fill: #e3e1d4;
  stroke: var(--hairline-strong);
  stroke-width: 1;
}

.globe-intro .globe-countries {
  fill: #faf7ed;
  stroke: #c9c3b2;
  stroke-width: 0.7;
}

:root[data-theme="dark"] .globe-intro .globe-sphere {
  fill: #1e2626;
}

:root[data-theme="dark"] .globe-intro .globe-countries {
  fill: #2b3434;
  stroke: #3d4747;
}

/* The dots match the map's travel markers: accent with a white rim. */
.globe-intro .globe-dots {
  fill: var(--accent);
  stroke: #fff;
  stroke-width: 1.2;
}

/* Place name tags, in the same ink, with a paper-coloured halo so they
   stay readable over the linework. */
.globe-label {
  fill: var(--ink);
  font-family: var(--serif);
  font-size: 12px;
  font-style: italic;
  paint-order: stroke;
  stroke: var(--paper);
  stroke-width: 3;
}

.globe-hint {
  bottom: 26px;
  color: var(--muted);
  font-family: var(--serif);
  font-size: 13px;
  font-style: italic;
  left: 0;
  margin: 0;
  position: absolute;
  right: 0;
  text-align: center;
}

/* Phones map the intro's 800-unit-wide drawing onto a narrow screen, which
   halves the rendered text size — these are viewBox units, not screen px. */
@media (max-width: 639px) {
  .globe-label {
    font-size: 22px;
    stroke-width: 5;
  }
}

/* CSS-level backup for the JS check: reduced-motion visitors go straight
   to the map. */
@media (prefers-reduced-motion: reduce) {
  .globe-intro {
    display: none;
  }
}

#map {
  height: 100vh;
  width: 100%;
  background: var(--paper);
}

.corner-nav {
  align-items: center;
  display: flex;
  gap: 22px;
  justify-content: space-between;
  left: 28px;
  pointer-events: none;
  position: fixed;
  right: 28px;
  top: 24px;
  z-index: 700;
}

.wordmark,
.nav-links,
.nav-link,
.theme-toggle {
  pointer-events: auto;
}

.wordmark {
  align-items: center;
  background: var(--panel);
  border: 1px solid var(--hairline);
  border-radius: 2px;
  box-shadow: 0 6px 22px rgba(20, 32, 32, 0.06);
  display: inline-flex;
  font-size: 12px;
  font-weight: 700;
  gap: 9px;
  letter-spacing: 0.11em;
  padding: 10px 13px 10px 11px;
  text-transform: uppercase;
}

.wordmark-mark {
  background: var(--accent);
  border-radius: 50%;
  display: block;
  height: 9px;
  position: relative;
  width: 9px;
}

.wordmark-mark::after {
  border: 1px solid var(--accent);
  border-radius: 50%;
  content: "";
  inset: -4px;
  opacity: 0.35;
  position: absolute;
}

.nav-links {
  align-items: center;
  background: var(--panel);
  border: 1px solid var(--hairline);
  box-shadow: 0 6px 22px rgba(20, 32, 32, 0.06);
  display: flex;
  gap: 2px;
  padding: 4px;
}

.nav-link {
  color: var(--muted);
  font-size: 12px;
  letter-spacing: 0.08em;
  padding: 6px 9px;
  text-transform: uppercase;
  transition: color 180ms ease, background 180ms ease;
}

.nav-link:hover,
.nav-link.is-current {
  background: var(--paper);
  color: var(--ink);
}

.theme-toggle {
  align-items: center;
  background: transparent;
  color: var(--muted);
  display: flex;
  font-size: 18px;
  height: 28px;
  justify-content: center;
  margin-left: 3px;
  overflow: hidden;
  position: relative;
  width: 28px;
}

.theme-icon {
  line-height: 1;
  position: absolute;
  transition: opacity 180ms ease, transform 180ms ease;
}

.theme-icon-sun {
  opacity: 1;
  transform: translateY(0);
}

.theme-icon-moon {
  opacity: 0;
  transform: translateY(10px);
}

:root[data-theme="dark"] .theme-icon-sun {
  opacity: 0;
  transform: translateY(-10px);
}

:root[data-theme="dark"] .theme-icon-moon {
  opacity: 1;
  transform: translateY(0);
}

:root[data-theme="light"] .theme-icon-sun {
  opacity: 1;
  transform: translateY(0);
}

.leaflet-container {
  background-color: #e6e6e6;
  font-family: var(--sans);
}

:root[data-theme="dark"] .leaflet-container {
  background-color: #242b2b;
}

.leaflet-control-attribution {
  background: color-mix(in srgb, var(--panel) 82%, transparent) !important;
  color: var(--muted);
  font-size: 10px;
}

.leaflet-control-attribution a {
  color: var(--muted);
}

/* Warm the basemap into the site's paper palette, so the map reads as if
   printed on the same cream stock as the rest of the page. Dark mode keeps
   its own untinted night tiles. */
.leaflet-tile-pane {
  filter: sepia(0.24) saturate(0.85) brightness(1.01);
}

:root[data-theme="dark"] .leaflet-tile-pane {
  filter: none;
}

.map-hint {
  background: var(--panel);
  border: 1px solid var(--hairline);
  bottom: 18px;
  box-shadow: var(--shadow);
  color: var(--muted);
  font-family: var(--serif);
  font-size: 13px;
  font-style: italic;
  left: 18px;
  margin: 0;
  max-width: 300px;
  padding: 10px 14px;
  position: fixed;
  z-index: 700;
}

.recent-card {
  background: var(--panel);
  border: 1px solid var(--hairline);
  bottom: 112px;
  box-shadow: var(--shadow);
  left: 18px;
  padding: 12px 14px 8px;
  position: fixed;
  width: 240px;
  z-index: 700;
}

.recent-title {
  color: var(--accent-deep);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  margin: 0 0 8px;
  text-transform: uppercase;
}

.recent-item {
  align-items: center;
  background: transparent;
  display: flex;
  gap: 10px;
  padding: 6px 0;
  text-align: left;
  width: 100%;
}

.recent-item img {
  background: linear-gradient(135deg, rgba(239, 105, 79, 0.16), rgba(91, 136, 132, 0.19));
  border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(21, 37, 37, 0.18);
  height: 40px;
  image-orientation: from-image;
  object-fit: cover;
  width: 40px;
}

.recent-item img.is-missing {
  visibility: hidden;
}

.recent-text {
  display: grid;
  gap: 1px;
  min-width: 0;
}

.recent-place {
  color: var(--ink);
  font-family: var(--serif);
  font-size: 14px;
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.recent-date {
  color: var(--muted);
  font-size: 11px;
}

.recent-item:hover .recent-place {
  color: var(--accent-deep);
}

@media (max-width: 767px) {
  /* Phones: the bottom edge belongs to the tip card and the photo panel,
     so Recently tucks under the logo instead. */
  .recent-card {
    bottom: auto;
    left: 12px;
    top: 64px;
    width: 200px;
  }

  .recent-card .recent-item img {
    height: 34px;
    width: 34px;
  }
}

.travel-marker {
  background: var(--accent);
  border: 3px solid #fff;
  border-radius: 50%;
  box-shadow: 0 2px 8px rgba(21, 37, 37, 0.24);
  pointer-events: none;
  transition: transform 180ms ease, fill 180ms ease;
}

.travel-marker-target {
  pointer-events: all;
}

/* No focus ring after a mouse click; keyboard focus keeps its outline. */
.leaflet-interactive:focus:not(:focus-visible) {
  outline: none;
}

.travel-marker.is-hovered,
.travel-marker.is-active {
  fill: var(--accent-deep);
  transform-box: fill-box;
  transform-origin: center;
  transform: scale(1.28);
}

.travel-marker.is-active {
  box-shadow: 0 0 0 5px rgba(239, 105, 79, 0.24), 0 3px 10px rgba(21, 37, 37, 0.3);
}

/* Emoji markers (place.icon in data.js). The outer div is positioned by
   Leaflet, so hover scaling happens on the inner span only. */
.travel-marker-icon {
  align-items: center;
  display: flex;
  font-size: 27px;
  justify-content: center;
  line-height: 1;
  pointer-events: none;
  text-shadow: 0 2px 8px rgba(21, 37, 37, 0.24);
}

.travel-marker-icon span {
  display: block;
  transition: transform 180ms ease;
}

.travel-marker-icon.is-hovered span {
  transform: scale(1.28);
}

.leaflet-tooltip.start-bubble {
  background: transparent;
  border: 0;
  box-shadow: none;
  color: var(--accent-deep);
  font-family: var(--serif);
  font-size: 14px;
  font-style: italic;
  padding: 0;
  pointer-events: none;
}

.leaflet-tooltip.start-bubble::before {
  display: none;
}

.leaflet-tooltip.start-bubble span {
  display: block;
  text-shadow: 0 0 8px var(--paper), 0 1px 2px var(--paper);
}

:root[data-theme="dark"] .leaflet-tooltip.start-bubble {
  color: var(--accent);
}

@media (prefers-reduced-motion: no-preference) {
  .leaflet-tooltip.start-bubble span {
    animation: start-bob 2.4s ease-in-out infinite;
  }
}

@keyframes start-bob {
  0%,
  100% {
    transform: translateY(0);
  }

  50% {
    transform: translateY(-5px);
  }
}

.leaflet-tooltip {
  background: var(--ink);
  border: 0;
  border-radius: 1px;
  box-shadow: none;
  color: var(--paper);
  font-size: 12px;
  padding: 6px 8px;
  pointer-events: none;
}

.leaflet-tooltip::before {
  border-right-color: var(--ink);
}

.place-panel {
  background: var(--panel);
  bottom: 0;
  box-shadow: var(--shadow);
  max-width: 100%;
  opacity: 0;
  overflow: hidden;
  pointer-events: none;
  position: fixed;
  right: 0;
  top: 0;
  transform: translateX(100%);
  transition: opacity 220ms ease, transform 320ms cubic-bezier(0.22, 1, 0.36, 1);
  width: min(420px, 100vw);
  z-index: 800;
}

.place-panel.is-open {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(0);
}

.panel-inner {
  height: 100%;
  overflow-y: auto;
  padding: 112px 30px 38px;
}

.panel-header {
  align-items: flex-start;
  border-bottom: 1px solid var(--hairline);
  display: flex;
  gap: 16px;
  justify-content: space-between;
  padding-bottom: 22px;
}

.eyebrow {
  color: var(--accent-deep);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  margin: 0 0 12px;
  text-transform: uppercase;
}

.panel-header h1 {
  font-family: var(--serif);
  font-size: clamp(28px, 5vw, 38px);
  font-weight: 400;
  letter-spacing: -0.04em;
  line-height: 1.05;
  margin: 0;
}

.place-summary {
  color: var(--muted);
  font-size: 12px;
  margin: 13px 0 0;
}

.icon-button {
  align-items: center;
  background: transparent;
  color: var(--muted);
  display: inline-flex;
  font-size: 27px;
  font-weight: 300;
  height: 34px;
  justify-content: center;
  line-height: 1;
  transition: color 180ms ease, transform 180ms ease;
  width: 34px;
}

.icon-button:hover {
  color: var(--ink);
  transform: rotate(90deg);
}

.photo-days {
  margin-top: 12px;
}

.photo-day {
  margin-top: 22px;
}

.photo-day-header {
  align-items: center;
  border-top: 1px solid var(--hairline);
  display: flex;
  justify-content: space-between;
  padding-top: 12px;
}

.photo-day-header .photo-date {
  margin: 0;
}

.day-nav {
  align-items: center;
  display: flex;
  gap: 2px;
}

.day-nav .strip-counter {
  font-size: 13px;
  margin-right: 6px;
}

.photo-strip {
  display: flex;
  gap: 14px;
  margin-top: 12px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

.photo-strip::-webkit-scrollbar {
  display: none;
}

.photo-strip .photo-entry {
  flex: 0 0 100%;
  scroll-snap-align: start;
}

.photo-strip .empty-state {
  flex: 0 0 100%;
}

.strip-counter {
  color: var(--muted);
  font-family: var(--serif);
  font-size: 15px;
  font-style: italic;
  margin: 0;
}

.strip-arrow {
  background: transparent;
  color: var(--muted);
  font-size: 18px;
  padding: 4px 10px;
  transition: color 180ms ease;
}

.strip-arrow:hover:not(:disabled) {
  color: var(--accent-deep);
}

.strip-arrow:disabled {
  cursor: default;
  opacity: 0.35;
}

.view-all {
  background: transparent;
  border: 1px solid var(--hairline-strong);
  color: var(--ink);
  display: block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  margin-top: 16px;
  padding: 11px 14px;
  text-transform: uppercase;
  transition: border-color 180ms ease, color 180ms ease;
  width: 100%;
}

.view-all:hover {
  border-color: var(--accent-deep);
  color: var(--accent-deep);
}

.photo-entry {
  animation: photo-in 420ms both;
  animation-delay: calc(var(--photo-index) * 55ms);
}

@keyframes photo-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.photo-image-wrap {
  background: linear-gradient(135deg, rgba(239, 105, 79, 0.16), rgba(91, 136, 132, 0.19));
  /* A thin white mat and soft shadow, like a print laid on paper. Prints
     stay white-bordered in dark mode too — that's what makes them prints. */
  border: 5px solid #fff;
  box-shadow: 0 2px 10px rgba(21, 37, 37, 0.16);
  overflow: hidden;
  position: relative;
}

/* Only a missing photo needs a guaranteed box for its placeholder text;
   a loaded photo sizes its own card exactly. */
.photo-image-wrap:has(img.is-missing) {
  min-height: 170px;
}

.photo-image-wrap::after {
  color: var(--muted);
  content: "Add this image to photos/";
  font-size: 11px;
  left: 50%;
  letter-spacing: 0.04em;
  position: absolute;
  text-align: center;
  top: 50%;
  transform: translate(-50%, -50%);
  white-space: nowrap;
  z-index: 0;
}

.photo-image-wrap img {
  /* Never cropped: photos keep their full frame. Tall photos stop growing
     at the height cap and sit centred on the white mat instead. */
  background: #fff;
  display: block;
  height: auto;
  image-orientation: from-image;
  max-height: 460px;
  object-fit: contain;
  position: relative;
  width: 100%;
  z-index: 1;
}

.photo-image-wrap img.is-missing {
  visibility: hidden;
}

.photo-details {
  padding-top: 10px;
}

.photo-date {
  color: var(--accent-deep);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.12em;
  margin: 0 0 4px;
  text-transform: uppercase;
}

.photo-caption {
  color: var(--ink);
  font-family: var(--serif);
  font-size: 18px;
  line-height: 1.25;
  margin: 0;
}

.note-link {
  background: transparent;
  color: var(--accent-deep);
  display: block;
  font-family: var(--serif);
  font-size: 14px;
  font-style: italic;
  margin-top: 8px;
  padding: 0;
  text-align: left;
  transition: color 180ms ease;
}

.note-link:hover {
  color: var(--accent);
}

.note-view {
  background: var(--paper);
  inset: 0;
  opacity: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  pointer-events: none;
  position: fixed;
  transition: opacity 220ms ease;
  z-index: 950;
}

.note-view.is-open {
  opacity: 1;
  pointer-events: auto;
}

.note-inner {
  margin: 0 auto;
  max-width: 640px;
  padding: 56px clamp(20px, 5vw, 40px) 90px;
}

.note-close {
  position: fixed;
  right: 20px;
  top: 16px;
}

.note-photo {
  margin: 0 0 30px;
}

.note-photo img {
  display: block;
  image-orientation: from-image;
  margin: 0 auto;
  max-height: 72vh;
  max-width: 100%;
}

.note-view h2 {
  font-family: var(--serif);
  font-size: clamp(24px, 3.4vw, 32px);
  font-weight: 400;
  margin: 4px 0 22px;
}

.note-body p {
  color: var(--ink);
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.75;
  margin: 0 0 1.2em;
}

.empty-state {
  border: 1px dashed var(--hairline-strong);
  color: var(--muted);
  font-size: 13px;
  padding: 24px 18px;
  text-align: center;
}

.panel-handle {
  display: none;
}

.gallery {
  background: var(--paper);
  inset: 0;
  opacity: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  pointer-events: none;
  position: fixed;
  transition: opacity 220ms ease;
  z-index: 900;
}

.gallery.is-open {
  opacity: 1;
  pointer-events: auto;
}

.gallery-inner {
  margin: 0 auto;
  max-width: 1280px;
  padding: 48px clamp(20px, 5vw, 64px) 72px;
}

.gallery-header {
  align-items: start;
  border-bottom: 1px solid var(--hairline-strong);
  display: flex;
  justify-content: space-between;
  margin-bottom: 34px;
  padding-bottom: 22px;
}

.gallery-header h2 {
  font-family: var(--serif);
  font-size: clamp(26px, 4vw, 38px);
  font-weight: 400;
  margin: 6px 0 0;
}

.gallery-grid {
  display: grid;
  gap: 42px 26px;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}

@media (max-width: 767px) {
  .gallery-grid {
    gap: 30px 16px;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  }
}

.lightbox {
  align-items: center;
  background: rgba(13, 20, 20, 0.91);
  display: flex;
  inset: 0;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  position: fixed;
  transition: opacity 220ms ease;
  z-index: 1000;
}

.lightbox.is-open {
  opacity: 1;
  pointer-events: auto;
}

.lightbox-content {
  max-width: min(78vw, 920px);
  position: relative;
}

.lightbox-image-wrap {
  align-items: center;
  background: #273333;
  display: flex;
  justify-content: center;
  min-height: 230px;
  min-width: min(62vw, 650px);
  position: relative;
}

.lightbox-image-wrap img {
  display: block;
  image-orientation: from-image;
  max-height: 72vh;
  max-width: 78vw;
  object-fit: contain;
}

.lightbox-image-wrap img.is-missing {
  display: none;
}

.lightbox-missing {
  color: #d7dfdb;
  font-size: 13px;
  line-height: 1.6;
  padding: 70px 60px;
  text-align: center;
}

.lightbox-missing span {
  color: #9daaa5;
  font-size: 11px;
}

.lightbox-caption {
  color: #eef1ec;
  padding-top: 14px;
}

.lightbox-caption p {
  color: #e9836f;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.13em;
  margin: 0 0 5px;
  text-transform: uppercase;
}

.lightbox-caption h2 {
  font-family: var(--serif);
  font-size: 21px;
  font-weight: 400;
  line-height: 1.2;
  margin: 0;
}

.lightbox-close {
  color: #d8e0dc;
  position: absolute;
  right: 28px;
  top: 22px;
}

.lightbox-close:hover {
  color: #fff;
}

.lightbox-arrow {
  background: transparent;
  color: #d8e0dc;
  font-size: 34px;
  font-weight: 300;
  height: 60px;
  margin: 0 clamp(10px, 4vw, 60px);
  transition: color 180ms ease, transform 180ms ease;
  width: 45px;
}

.lightbox-arrow:hover {
  color: #fff;
  transform: scale(1.12);
}

.lightbox-arrow:disabled {
  cursor: default;
  opacity: 0.3;
}

/* About page */
.about-page {
  min-height: 100vh;
}

.about-content {
  margin: 0 auto;
  max-width: 820px;
  padding: 19vh 36px 90px;
}

.about-content h1 {
  font-family: var(--serif);
  font-size: clamp(46px, 8vw, 86px);
  font-weight: 400;
  letter-spacing: -0.06em;
  line-height: 0.96;
  margin: 0;
}

.about-content h1 em {
  color: var(--accent-deep);
  font-style: italic;
}

.title-note {
  color: var(--muted);
  font-family: var(--serif);
  font-size: 17px;
  font-style: italic;
  margin: 16px 0 0;
  max-width: 520px;
}

.about-rule {
  border-top: 1px solid var(--hairline-strong);
  margin: 58px 0 48px;
  width: 100%;
}

.about-grid {
  align-items: start;
  display: grid;
  gap: clamp(28px, 7vw, 90px);
  grid-template-columns: minmax(160px, 0.65fr) 1fr;
}

.portrait-frame {
  align-items: center;
  aspect-ratio: 4 / 5;
  background: linear-gradient(145deg, rgba(239, 105, 79, 0.35), rgba(91, 136, 132, 0.38));
  color: var(--ink);
  display: flex;
  font-family: var(--serif);
  font-size: 20px;
  justify-content: center;
  line-height: 1.1;
  text-align: center;
}

.about-copy {
  color: var(--muted);
  max-width: 440px;
}

.about-copy p {
  margin: 0 0 22px;
}

.about-copy .about-greeting {
  color: var(--accent-deep);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  margin: 0 0 6px;
  text-transform: uppercase;
}

.about-copy .lead {
  color: var(--ink);
  font-family: var(--serif);
  font-size: clamp(22px, 3vw, 29px);
  line-height: 1.22;
}

.about-copy .signature {
  color: var(--ink);
  font-family: var(--serif);
  font-size: 19px;
  margin-top: 35px;
}

.about-copy .signature a {
  border-bottom: 1px solid var(--hairline-strong);
  transition: color 0.2s ease, border-color 0.2s ease;
}

.about-copy .signature a:hover,
.about-copy .signature a:focus-visible {
  border-bottom-color: currentColor;
  color: var(--accent);
}

.back-link {
  align-items: center;
  border-bottom: 1px solid var(--hairline-strong);
  display: inline-flex;
  font-size: 12px;
  gap: 9px;
  letter-spacing: 0.08em;
  margin-top: 74px;
  padding-bottom: 5px;
  text-transform: uppercase;
  transition: color 180ms ease, border-color 180ms ease;
}

.back-link:hover {
  border-color: var(--accent);
  color: var(--accent-deep);
}

.back-link span {
  font-size: 19px;
  line-height: 0.5;
}

@media (max-width: 767px) {
  .corner-nav {
    left: 14px;
    right: 14px;
    top: 14px;
  }

  .wordmark {
    font-size: 10px;
    padding: 8px 10px 8px 9px;
  }

  .nav-links {
    padding: 3px;
  }

  .nav-link {
    font-size: 10px;
    padding: 5px 7px;
  }

  .place-panel {
    border-radius: 15px 15px 0 0;
    height: 70vh;
    top: auto;
    transform: translateY(100%);
    width: 100%;
  }

  .place-panel.is-open {
    transform: translateY(0);
  }

  .panel-handle {
    background: var(--hairline-strong);
    border-radius: 10px;
    display: block;
    height: 4px;
    left: calc(50% - 21px);
    position: absolute;
    top: 10px;
    width: 42px;
  }

  .panel-inner {
    padding: 38px 20px 30px;
  }

  .panel-header {
    padding-bottom: 17px;
  }

  .panel-header h1 {
    font-size: 31px;
  }

  .photo-strip {
    margin-top: 10px;
  }

  .photo-image-wrap:has(img.is-missing) {
    min-height: 145px;
  }

  .travel-marker {
    border-width: 3px;
  }

  .lightbox-content {
    max-width: 84vw;
  }

  .lightbox-image-wrap {
    min-width: 84vw;
  }

  .lightbox-image-wrap img {
    max-width: 84vw;
  }

  .lightbox-arrow {
    bottom: 24px;
    font-size: 28px;
    margin: 0;
    position: absolute;
    z-index: 2;
  }

  .lightbox-prev {
    left: 18px;
  }

  .lightbox-next {
    right: 18px;
  }

  .lightbox-caption {
    padding: 14px 4px 0;
  }

  .about-content {
    padding: 140px 24px 64px;
  }

  .about-content h1 {
    font-size: clamp(46px, 14vw, 72px);
  }

  .about-rule {
    margin: 40px 0 32px;
  }

  .about-grid {
    grid-template-columns: 1fr;
  }

  .portrait-frame {
    max-width: 210px;
  }

  .back-link {
    margin-top: 45px;
  }
}

/* Private admin tool */
.admin-page {
  background: var(--paper);
  min-height: 100vh;
}

.admin-shell {
  margin: 0 auto;
  max-width: 1280px;
  padding: 116px 32px 70px;
}

.admin-heading {
  align-items: end;
  border-bottom: 1px solid var(--hairline-strong);
  display: flex;
  gap: 32px;
  justify-content: space-between;
  padding-bottom: 30px;
}

.admin-heading h1 {
  font-family: var(--serif);
  font-size: clamp(42px, 6vw, 74px);
  font-weight: 400;
  letter-spacing: -0.06em;
  line-height: 0.95;
  margin: 0;
}

.admin-heading h1 em {
  color: var(--accent-deep);
  font-style: italic;
}

.private-notice {
  color: var(--accent-deep);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.13em;
  line-height: 1.5;
  margin: 0;
  max-width: 210px;
  text-align: right;
  text-transform: uppercase;
}

.admin-layout {
  align-items: start;
  display: grid;
  gap: 30px;
  grid-template-columns: minmax(0, 1.55fr) minmax(290px, 0.75fr);
  margin-top: 30px;
}

.admin-main,
.admin-aside {
  display: grid;
  gap: 24px;
}

.admin-card {
  background: var(--panel);
  border: 1px solid var(--hairline);
  box-shadow: 0 8px 24px rgba(20, 32, 32, 0.04);
  padding: 24px;
}

.admin-card h2 {
  font-family: var(--serif);
  font-size: 25px;
  font-weight: 400;
  letter-spacing: -0.035em;
  margin: 0;
}

.admin-card h3 {
  font-size: 11px;
  letter-spacing: 0.12em;
  margin: 0;
  text-transform: uppercase;
}

.admin-card-header {
  align-items: start;
  display: flex;
  gap: 16px;
  justify-content: space-between;
  margin-bottom: 18px;
}

.admin-card-header p,
.admin-intro,
.admin-help {
  color: var(--muted);
  font-size: 12px;
  margin: 6px 0 0;
}

.dropzone {
  align-items: center;
  border: 1px dashed var(--hairline-strong);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 170px;
  padding: 24px;
  text-align: center;
  transition: background 180ms ease, border-color 180ms ease;
}

.dropzone:hover,
.dropzone.is-dragging {
  background: rgba(239, 105, 79, 0.08);
  border-color: var(--accent);
}

.dropzone strong {
  font-family: var(--serif);
  font-size: 23px;
  font-weight: 400;
}

.dropzone span {
  color: var(--muted);
  font-size: 12px;
  margin-top: 7px;
}

.button-row {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
}

.admin-button {
  background: var(--ink);
  border: 1px solid var(--ink);
  color: var(--paper-soft);
  font-size: 11px;
  letter-spacing: 0.08em;
  padding: 10px 13px;
  text-transform: uppercase;
  transition: background 180ms ease, border-color 180ms ease, color 180ms ease;
}

.admin-button:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

.admin-button.secondary {
  background: transparent;
  border-color: var(--hairline-strong);
  color: var(--ink);
}

.admin-button.secondary:hover {
  border-color: var(--accent);
  color: var(--accent-deep);
}

.admin-button.small {
  font-size: 10px;
  padding: 7px 9px;
}

.admin-button:disabled {
  cursor: not-allowed;
  opacity: 0.42;
}

.file-input {
  display: none;
}

.setting-grid {
  display: grid;
  gap: 12px 18px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-top: 20px;
}

.setting-grid .wide {
  grid-column: 1 / -1;
}

.check-row {
  align-items: center;
  border-top: 1px solid var(--hairline);
  display: flex;
  gap: 9px;
  padding-top: 14px;
}

.check-row label {
  font-size: 12px;
}

.check-row input,
.photo-check input {
  accent-color: var(--accent);
}

.mode-status {
  align-items: start;
  background: rgba(91, 136, 132, 0.1);
  border-left: 3px solid #5b8884;
  color: var(--ink);
  display: flex;
  font-size: 12px;
  gap: 10px;
  line-height: 1.45;
  padding: 11px 12px;
}

.mode-status strong {
  display: block;
  font-size: 10px;
  letter-spacing: 0.1em;
  margin-bottom: 2px;
  text-transform: uppercase;
}

.warning-list {
  display: grid;
  gap: 8px;
  margin-top: 18px;
}

.warning {
  background: rgba(239, 105, 79, 0.09);
  border-left: 3px solid var(--accent);
  color: var(--ink);
  font-size: 12px;
  padding: 10px 12px;
}

.warning strong {
  display: block;
  font-size: 10px;
  letter-spacing: 0.08em;
  margin-bottom: 2px;
  text-transform: uppercase;
}

.group-list {
  display: grid;
  gap: 18px;
}

.group-list:empty::before {
  color: var(--muted);
  content: "Imported photo groups will appear here.";
  font-size: 12px;
  padding: 12px 0;
}

.group-card {
  border: 1px solid var(--hairline);
  min-width: 0;
  padding: 17px;
  transition: border-color 180ms ease, background 180ms ease;
}

.group-card.is-drop-target {
  background: rgba(239, 105, 79, 0.06);
  border-color: var(--accent);
}

.group-header {
  align-items: start;
  display: grid;
  gap: 14px;
  grid-template-columns: minmax(0, 1fr) auto;
}

.group-title-input {
  background: transparent;
  border: 0;
  border-bottom: 1px dashed var(--hairline-strong);
  color: var(--ink);
  cursor: text;
  font-family: var(--serif);
  font-size: 25px;
  outline: 0;
  padding: 0 0 5px;
  transition: border-color 180ms ease;
  width: 100%;
}

.group-title-input:hover {
  border-bottom-color: var(--accent-deep);
}

.group-title-input:focus {
  border-bottom-color: var(--accent);
  border-bottom-style: solid;
}

.rename-hint {
  color: var(--accent-deep);
  font-size: 12px;
  margin: 8px 0 0;
}

.group-actions {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  justify-content: end;
}

.group-actions select,
.load-actions select {
  background: var(--paper);
  border: 1px solid var(--hairline);
  color: var(--muted);
  font-size: 10px;
  max-width: 150px;
  padding: 7px;
}

.group-coords {
  display: grid;
  gap: 9px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin: 15px 0 17px;
  max-width: 360px;
}

.place-search {
  display: flex;
  gap: 8px;
  margin: 0 0 8px;
  max-width: 360px;
}

.place-search input {
  background: var(--paper-soft);
  border: 1px solid var(--hairline);
  color: var(--ink);
  flex: 1;
  font: inherit;
  min-width: 0;
  padding: 7px 9px;
}

.place-search-results {
  display: grid;
  gap: 4px;
  font-size: 12px;
  margin: 0 0 14px;
  max-width: 360px;
}

.place-search-result {
  background: var(--paper-soft);
  border: 1px solid var(--hairline);
  color: var(--ink);
  cursor: pointer;
  padding: 7px 9px;
  text-align: left;
  transition: border-color 180ms ease;
}

.place-search-result:hover {
  border-color: var(--accent-deep);
}

.field {
  color: var(--muted);
  display: block;
  font-size: 10px;
  letter-spacing: 0.08em;
  position: relative;
  text-transform: uppercase;
}

.field::after {
  color: var(--accent);
  content: "";
  height: 5px;
  opacity: 0;
  position: absolute;
  right: 7px;
  top: 7px;
  width: 5px;
}

.field.is-changed::after {
  background: var(--accent);
  border-radius: 50%;
  opacity: 1;
}

.field input,
.field textarea {
  background: var(--paper-soft);
  border: 1px solid var(--hairline);
  color: var(--ink);
  display: block;
  font: inherit;
  letter-spacing: 0;
  margin-top: 5px;
  outline: 0;
  padding: 8px 9px;
  text-transform: none;
  width: 100%;
}

.field input:focus,
.field textarea:focus {
  border-color: var(--accent);
}

.field textarea {
  min-height: 46px;
  resize: vertical;
}

.group-drop-note {
  border-top: 1px dashed var(--hairline);
  color: var(--muted);
  font-size: 10px;
  margin-top: 16px;
  padding-top: 9px;
}

.photo-grid {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

.photo-card {
  background: var(--paper-soft);
  border: 1px solid var(--hairline);
  cursor: grab;
  min-width: 0;
  padding: 9px;
}

.photo-card:active {
  cursor: grabbing;
}

.photo-card.is-dragging {
  opacity: 0.45;
}

.admin-thumb {
  align-items: center;
  aspect-ratio: 4 / 3;
  background: linear-gradient(135deg, rgba(239, 105, 79, 0.14), rgba(91, 136, 132, 0.18));
  display: flex;
  justify-content: center;
  overflow: hidden;
  position: relative;
}

.admin-thumb img {
  height: 100%;
  image-orientation: from-image;
  object-fit: cover;
  transition: transform 180ms ease;
  width: 100%;
}

.admin-thumb.is-placeholder::after {
  color: var(--muted);
  content: "Preview unavailable";
  font-size: 10px;
  position: absolute;
}

.photo-filename {
  color: var(--muted);
  font-size: 10px;
  margin: 8px 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.photo-fields {
  display: grid;
  gap: 8px;
}

.photo-meta-grid {
  display: grid;
  gap: 8px;
  grid-template-columns: 1fr 1fr;
}

.photo-actions {
  align-items: center;
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 9px;
  padding-top: 9px;
}

.photo-action {
  background: transparent;
  border: 1px solid var(--hairline);
  color: var(--muted);
  font-size: 11px;
  padding: 5px 7px;
}

.photo-action:hover {
  border-color: var(--accent);
  color: var(--accent-deep);
}

.photo-check {
  align-items: center;
  color: var(--muted);
  display: flex;
  font-size: 10px;
  gap: 5px;
  margin-left: auto;
}

.existing-section {
  border-top: 1px solid var(--hairline-strong);
  margin-top: 32px;
  padding-top: 28px;
}

.existing-section > .admin-card-header {
  margin-bottom: 18px;
}

.load-panel textarea {
  font-family: "SFMono-Regular", Consolas, monospace;
  min-height: 150px;
  width: 100%;
}

.load-actions {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  margin-top: 12px;
}

.load-status {
  color: var(--muted);
  font-size: 11px;
  margin: 10px 0 0;
}

.load-status.is-error {
  color: var(--accent-deep);
}

.orphan-list {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.6;
  margin: 12px 0 0;
}

.orphan-list ul {
  margin: 8px 0 0;
  padding-left: 18px;
}

.empty-admin {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.6;
}

.admin-footer-note {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.6;
  margin: 26px 0 0;
}

@media (max-width: 900px) {
  .admin-layout {
    grid-template-columns: 1fr;
  }

  .admin-aside {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 620px) {
  .admin-shell {
    padding: 94px 16px 48px;
  }

  .admin-heading {
    align-items: start;
    display: block;
  }

  .private-notice {
    margin-top: 16px;
    max-width: none;
    text-align: left;
  }

  .admin-card {
    padding: 17px;
  }

  .admin-aside {
    grid-template-columns: 1fr;
  }

  .setting-grid,
  .group-coords {
    grid-template-columns: 1fr;
  }

  .setting-grid .wide {
    grid-column: auto;
  }

  .group-header {
    display: block;
  }

  .group-actions {
    justify-content: start;
    margin-top: 13px;
  }
}