/* jefferochan.com — original code, design informed by the site's previous look */

:root {
  --page-bg: #efefef;
  --card-bg: #f6f6f6;
  --text: #444444;
  --heading: #213f52;
  --link: #6dc8fe;
  --link-hover: #009fff;
  --accent: #56bc8a;
  --muted: #aeaeae;
  --hero-overlay: rgba(0, 0, 0, 0.3);
}

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

body {
  background-color: var(--page-bg);
  color: var(--text);
  font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-weight: 300;
  font-size: 13px;
  line-height: 21px;
}

/* Homepage: black behind everything so iOS Safari's edge-to-edge zones
   never flash grey. */
body:has(.hero) {
  background-color: #000;
}

::selection { background: var(--accent); color: #fff; }

a {
  color: var(--link);
  text-decoration: none;
  transition: color 0.2s ease-in-out;
}
a:hover { color: var(--link-hover); }

img { max-width: 100%; display: block; }

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

.hero {
  /* Pinned to the viewport; the page scrolls beneath it (see body rule)
     so iOS Safari collapses its bars and grants the full screen. */
  position: fixed;
  inset: 0;
  background-color: #000;
  overflow: hidden;
}

/* Held black until the first photos are in (see site.js), then faded in
   whole. The mirrored canvas stays suppressed for the whole fade, not just
   the wait: the hero is semi-transparent while it fades, so a mirror at
   full strength behind it puts the photo on screen immediately and leaves
   only the signature and icons looking like they fade. */
.hero { transition: opacity 1s ease-in-out; }
.is-booting .hero { opacity: 0; }
html.is-booting, .is-booting body,
html.is-revealing, .is-revealing body { background-image: none !important; }

/* ---------- the boot loader ----------
   Black, a hairline bar keeping honest count of the real loads (see
   the boot gate in site.js); it fades the moment the boot lifts, and
   the no-script failsafe that clears is-booting clears this with it. */
.boot {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: #000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 34px;
  opacity: 1;
  transition: opacity 0.5s ease;
}
html:not(.is-booting) .boot { opacity: 0; pointer-events: none; }
.boot-meter { display: flex; flex-direction: column; align-items: center; gap: 12px; }
.boot-bar {
  width: 210px;
  height: 1px;
  background: rgba(255, 255, 255, 0.18);
  position: relative;
  overflow: hidden;
}
.boot-bar i {
  position: absolute;
  inset: 0;
  background: #fff;
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform 0.25s ease;
}
.boot-pct {
  font-size: 11px;
  letter-spacing: 3px;
  font-variant-numeric: tabular-nums;
  color: rgba(255, 255, 255, 0.7);
}

.hero-slide {
  /* Exactly the viewport: framing percentages from backstage map 1:1. */
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  opacity: 0;
  transition: opacity 0.75s ease-in-out;
}
.hero-slide.is-active { opacity: 1; }

.hero-overlay {
  position: absolute;
  inset: 0;
  background-color: var(--hero-overlay);
}

.hero-inner {
  position: relative;
  z-index: 5;
  height: 100%;
  height: 100dvh;
  max-width: 600px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  text-transform: uppercase;
  padding: 0 20px;
}

.hero-signature img,
.hero-signature canvas {
  display: block;
  width: 144px;
  height: auto;
  margin: 0 auto;
}

/* The signing happens on a canvas the script drops in beside the image
   (see site.js); while it writes -- and after -- the plain image steps
   aside, and before the first stroke it is nowhere to be seen. */
.sig img[hidden] { display: none; }
html.sig-hold .sig img {
  visibility: hidden;
  /* the no-JavaScript fallback: with no script ever arriving, the plain
     logo surfaces on its own -- pure CSS, no timer to miss. The first
     thing site.js does is call this off and own the hold itself. */
  animation: sig-noscript 0s linear 14s forwards;
}
@keyframes sig-noscript { to { visibility: visible; } }
html.sig-js .sig img { animation: none; }

.hero-social {
  --soc-icon: 16px;
  --soc-row-gap: 15px;
  margin-top: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  align-content: flex-start;
  column-gap: 22px;
  row-gap: 0;
  /* Reserve the second row up front and cancel it from the layout, so
     opening a set never nudges the signature above it. */
  min-height: calc(2 * var(--soc-icon) + var(--soc-row-gap));
  margin-bottom: calc(-1 * (var(--soc-icon) + var(--soc-row-gap)));
}
.hero-social .social-break { display: none; width: 100%; height: 0; }
/* the break sits on a flex line of its own, so the gap between the two
   lines comes from the second line's own margin, not row-gap */
.hero-social .is-row2 { margin-top: var(--soc-row-gap); }
.hero-social.is-open-music .social-break.for-music,
.hero-social.is-open-social .social-break.for-social { display: block; }
.hero-social a {
  color: #fff;
  display: inline-flex;
  position: relative;
  opacity: 0.9;
  transition: opacity 0.2s ease-in-out, transform 0.2s ease-in-out;
}
/* A 16px glyph is a small target for a finger; widen it without touching
   the layout the row is centred on. */
.hero-social a::after {
  content: "";
  position: absolute;
  inset: -8px;
}
/* Only devices that actually hover get the sustained lift; on a touch
   screen the lift would stick to the last icon tapped. */
@media (hover: hover) and (pointer: fine) {
  .hero-social a:hover { opacity: 1; transform: translateY(-2px); color: #fff; }
}
/* A tap gets a single hop instead, so the icon settles back down. The glyph
   moves, never the link itself: a link that slides out from under the finger
   ends up with mousedown and mouseup on different elements, and the click
   then resolves to an ancestor and does nothing. Keeping the animation off
   the link also leaves an unfurled icon's own animation untouched, which
   otherwise restarted and replayed the expand as the hop finished. */
.hero-social a.is-tapped svg { animation: icon-hop 0.42s cubic-bezier(0.34, 1.4, 0.5, 1); }
@keyframes icon-hop {
  0% { transform: translateY(0); }
  35% { transform: translateY(-7px); }
  70% { transform: translateY(0); }
  85% { transform: translateY(-2px); }
  100% { transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .hero-social a.is-tapped svg { animation: none; }
}
.hero-social svg { width: var(--soc-icon); height: var(--soc-icon); fill: currentColor; }

/* Grouped socials. Spotify and Instagram each lead a set of platforms; the
   row swaps between the default set and one group. Longer sets wrap onto
   a second line; both lines stay centred on the page. */
.hero-social .is-alt { display: none; }
.hero-social.is-open-music .is-alt.for-music,
.hero-social.is-open-social .is-alt.for-social { display: inline-flex; }
.hero-social.is-open-music .is-main:not(.for-music),
.hero-social.is-open-social .is-main:not(.for-social) { display: none; }
.hero-social [data-group] { cursor: pointer; }
/* the open group's leader stays lit so it reads as the current set */
.hero-social.is-open-music .for-music.is-main,
.hero-social.is-open-social .for-social.is-main { opacity: 1; color: #fff; }
.hero-social .is-alt {
  /* unfurls sideways out of the leader: --from carries the direction,
     --i staggers them so the set opens left to right */
  animation: social-unfurl 0.32s cubic-bezier(0.22, 0.61, 0.36, 1) backwards;
  animation-delay: calc(var(--i, 0) * 45ms);
}
@keyframes social-unfurl {
  from { opacity: 0; transform: translateX(var(--from, -18px)); }
  to { opacity: 0.9; transform: none; }
}
/* closing runs the same motion backwards: the icon that arrived last
   leaves first, so the set folds towards its leader */
.hero-social.is-closing .is-alt {
  animation-name: social-furl;
  animation-delay: calc((var(--n, 1) - 1 - var(--i, 0)) * 45ms);
  animation-fill-mode: forwards;
}
@keyframes social-furl {
  from { opacity: 0.9; transform: none; }
  to { opacity: 0; transform: translateX(var(--from, -18px)); }
}
@media (prefers-reduced-motion: reduce) {
  .hero-social.is-closing .is-alt { animation: none; }
}
/* once the set has folded away, the default row eases back in rather than
   snapping into place */
.hero-social .is-back {
  animation: social-return 0.34s cubic-bezier(0.22, 0.61, 0.36, 1) backwards;
  animation-delay: calc(var(--ri, 0) * 55ms);
}
@keyframes social-return {
  from { opacity: 0; transform: translateY(5px) scale(0.86); }
  to { opacity: 0.9; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-social .is-back { animation: none; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-social .is-alt { animation: none; }
}

.home-link {
  margin-top: 38px;
  display: inline-flex;
  color: #fff;
  opacity: 0;
  pointer-events: none;
  transition: opacity 1s ease-in-out, transform 0.2s ease-in-out;
}
.home-link.is-shown { opacity: 0.9; pointer-events: auto; }
@media (hover: hover) and (pointer: fine) {
  .home-link:hover { opacity: 1; transform: translateY(-2px); color: #fff; }
}
.home-link svg { width: 22px; height: 22px; fill: currentColor; }

.social-inert {
  color: #fff;
  display: inline-flex;
  opacity: 0.9;
}
.social-inert svg { width: 16px; height: 16px; fill: currentColor; }

.hero-dots {
  --dot: 7px;
  --gap: 8px;
  position: absolute;
  top: calc(16px + env(safe-area-inset-top, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 6;
  display: flex;
  align-items: center;
  gap: var(--gap);
  max-width: 92vw;
  flex-wrap: wrap;
  justify-content: center;
}

.hero-dot {
  /* visual dot is --dot wide; the button keeps a bigger touch target */
  width: calc(var(--dot) + 10px);
  height: calc(var(--dot) + 10px);
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  position: relative;
  cursor: pointer;
}
.hero-dot::before {
  content: "";
  position: absolute;
  inset: 5px;
  border: 1px solid rgba(255, 255, 255, 0.9);
  border-radius: 50%;
  transition: background-color 0.25s ease-in-out, transform 0.25s ease-in-out;
}
.hero-dot:hover::before { transform: scale(1.25); }
.hero-dot.is-active::before { background-color: #fff; }
.hero-dot.is-small::before { transform: scale(0.6); opacity: 0.7; }
.hero-dot.is-small:hover::before { transform: scale(0.8); }

.hero-dots-viewport {
  display: flex;
  align-items: center;
  overflow: hidden;
}
.hero-dots-strip {
  display: inline-flex;
  gap: var(--gap);
  transition: transform 0.45s ease-in-out;
  will-change: transform;
}

.hero-dots-divider {
  width: 1px;
  height: calc(var(--dot) + 4px);
  background-color: rgba(255, 255, 255, 0.65);
  margin: 0 3px;
  flex-shrink: 0;
}

.hero-caption {
  position: absolute;
  bottom: calc(34px + env(safe-area-inset-bottom, 0px));
  left: 0;
  right: 0;
  z-index: 6;
  text-align: center;
  color: rgba(255, 255, 255, 0.8);
  font-size: 11px;
  letter-spacing: 0.5px;
  padding: 0 20px;
  transition: opacity 0.4s ease-in-out;
}
.hero-caption:empty { display: none; }

@keyframes cr-fade {
  0%, 74.07% { opacity: 1; }
  100% { opacity: 0; }
}

.hero-copyright {
  /* visible 10s, then a 3.5s fade-out */
  animation: cr-fade 13.5s linear forwards;
  pointer-events: none;
  position: absolute;
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  left: 0;
  right: 0;
  z-index: 6;
  text-align: center;
  color: rgba(255, 255, 255, 0.55);
  font-size: 10px;
  letter-spacing: 0.5px;
}
.cr-short { display: none; }

/* ---------- Cards (permalink pages) ---------- */

.card {
  background-color: var(--card-bg);
  transition: opacity 0.3s ease-in-out;
}
a.card-media:hover { opacity: 0.85; }

.card-media img { width: 100%; height: auto; }

.card-body { padding: 14px 20px 16px; }
.card-body p { margin: 0 0 10px; }
.card-body p:last-child { margin-bottom: 0; }

.card-title {
  font-family: "Montserrat", "Open Sans", sans-serif;
  font-size: 14px;
  font-weight: 600;
  color: var(--heading);
  margin: 0 0 10px;
}
.card-title a { color: var(--heading); }

.card-date {
  margin-top: 12px;
  font-size: 11px;
}
.card-date a { color: var(--heading); }
.card-date a:hover { color: var(--link-hover); }

.card-embed { position: relative; width: 100%; }
.card-embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.card-embed--instagram { padding-top: 120%; }
.card-embed--youtube { padding-top: 56.25%; }

blockquote {
  border-left: 2px solid var(--accent);
  margin: 10px 0 10px 20px;
  padding-left: 15px;
}

/* ---------- Post page ---------- */

.topbar {
  background-color: #111;
  text-align: center;
  padding: 26px 0 22px;
}
.topbar img { width: 96px; height: auto; margin: 0 auto; }

.single-wrap {
  max-width: 660px;
  margin: 0 auto;
  padding: 50px 15px 30px;
}

.single-wrap .card-body { padding: 18px 24px 20px; }

.post-tags { margin-top: 14px; }
.post-tags span {
  display: inline-block;
  margin-right: 8px;
  color: var(--muted);
  font-size: 11px;
}

.post-nav {
  display: flex;
  justify-content: space-between;
  margin-top: 30px;
  font-size: 12px;
}

/* ---------- Archive ---------- */

.archive-wrap {
  max-width: 900px;
  margin: 0 auto;
  padding: 50px 15px 30px;
}

.archive-month {
  font-family: "Montserrat", "Open Sans", sans-serif;
  font-size: 13px;
  font-weight: 600;
  color: var(--heading);
  letter-spacing: 1px;
  text-transform: uppercase;
  margin: 35px 0 15px;
}

.archive-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 10px;
}

.archive-grid a { display: block; position: relative; }
.archive-grid img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  transition: opacity 0.2s ease-in-out;
}
.archive-grid a:hover img { opacity: 0.8; }

.archive-text {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  aspect-ratio: 1 / 1;
  background-color: var(--card-bg);
  color: var(--text);
  font-size: 11px;
  line-height: 16px;
  padding: 10px;
  overflow: hidden;
}

/* ---------- Backstage ---------- */

.bs-wrap {
  max-width: 660px;
  margin: 0 auto;
  padding: 40px 15px 50px;
}

.bs-fab {
  position: fixed;
  left: 22px;
  top: 165px;
  z-index: 60;
  touch-action: none;
}
.bs-fab-button {
  width: 46px;
  height: 46px;
  border: 0;
  border-radius: 50%;
  cursor: grab;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--heading);
  background-color: rgba(255, 255, 255, 0.85);
  box-shadow: 0 2px 14px rgba(0, 0, 0, 0.18);
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .bs-fab-button {
    background-color: rgba(255, 255, 255, 0.45);
    -webkit-backdrop-filter: blur(16px) saturate(160%);
    backdrop-filter: blur(16px) saturate(160%);
  }
}
.bs-fab-button svg { width: 20px; height: 20px; fill: currentColor; }
.bs-fab.is-dragging .bs-fab-button { cursor: grabbing; }

.bs-fab-cards {
  display: none;
  position: absolute;
  top: calc(100% + 10px);
  left: 0;
  flex-direction: column;
  gap: 8px;
  min-width: 150px;
}
.bs-fab.is-open .bs-fab-cards { display: flex; }
.bs-fab.open-up .bs-fab-cards { top: auto; bottom: calc(100% + 10px); }
.bs-fab.open-left .bs-fab-cards { left: auto; right: 0; }

@media (max-width: 700px) {
  .bs-fab {
    left: auto;
    top: auto;
    right: 18px;
    bottom: calc(22px + env(safe-area-inset-bottom, 0px));
  }
  .scrollup {
    right: auto;
    left: 18px;
    bottom: calc(22px + env(safe-area-inset-bottom, 0px));
  }
}
.bs-fab-card {
  padding: 11px 14px;
  border-radius: 10px;
  font-size: 12px;
  color: var(--text);
  background-color: rgba(255, 255, 255, 0.85);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.14);
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .bs-fab-card {
    background-color: rgba(255, 255, 255, 0.5);
    -webkit-backdrop-filter: blur(16px) saturate(160%);
    backdrop-filter: blur(16px) saturate(160%);
  }
}
.bs-fab-card.is-active { background-color: var(--heading); color: #fff; font-weight: 600; }
.bs-fab-card:hover:not(.is-active) { color: var(--heading); }

}

.bs-title {
  font-family: "Montserrat", "Open Sans", sans-serif;
  font-size: 20px;
  color: var(--heading);
  margin: 0 0 15px;
}

.bs-sub {
  font-family: "Montserrat", "Open Sans", sans-serif;
  font-size: 13px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--heading);
  margin: 35px 0 15px;
}

.bs-actions {
  margin: 20px 0;
  display: flex;
  gap: 10px;
}

.bs-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid #d9d9d9;
  border-radius: 50%;
  color: #7d8a94;
  background-color: transparent;
  cursor: pointer;
  font: inherit;
  transition: color 0.15s ease-in-out, border-color 0.15s ease-in-out, background-color 0.15s ease-in-out;
}
.bs-icon:hover { border-color: var(--heading); color: var(--heading); background-color: rgba(33, 63, 82, 0.05); }
.bs-icon svg { width: 14px; height: 14px; fill: currentColor; }
.bs-icon.is-on { background-color: var(--accent); border-color: var(--accent); color: #fff; }

@keyframes bs-blink { 50% { opacity: 0.35; } }
.bs-item.is-editing .bs-edit-btn { animation: bs-blink 1.5s ease-in-out infinite; }

.bs-item .bs-focus-btn { display: none; }
.bs-item.is-editing .bs-focus-btn { display: inline-flex; }
.bs-item.is-editing .bs-pin-toggle { display: none; }

.bs-del {
  position: absolute;
  left: -42px;
  top: 50%;
  transform: translateY(-50%);
  display: none;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid rgba(192, 57, 43, 0.45);
  border-radius: 50%;
  color: #c0392b;
  background-color: var(--page-bg);
  cursor: pointer;
}
.bs-del svg { width: 14px; height: 14px; fill: currentColor; }
.bs-del:hover { background-color: #c0392b; border-color: #c0392b; color: #fff; }
.bs-item.is-editing .bs-del { display: flex; }

.bs-wrap.is-arrange .bs-item { cursor: grab; user-select: none; touch-action: none; padding: 6px 10px; }
.bs-wrap.is-arrange .bs-item-actions,
.bs-wrap.is-arrange .bs-del,
.bs-wrap.is-arrange .bs-desc-input { display: none; }
/* the whole card is the drag handle while arranging — the file name and the
   thumbnails must not swallow the grab (or start a text selection) */
.bs-wrap.is-arrange .bs-name,
.bs-wrap.is-arrange .bs-thumb { pointer-events: none; }
.bs-wrap.is-arrange .bs-thumb-land { width: 84px; height: 47px; }
.bs-wrap.is-arrange .bs-thumb-port { width: 26px; height: 48px; }
.bs-wrap.is-arrange .bs-item.is-dragging {
  cursor: grabbing;
  z-index: 30;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
  opacity: 0.96;
}

.bs-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  /* stays locked to the top while the signature header scrolls away */
  position: sticky;
  top: 0;
  z-index: 40;
  margin: 0 -15px;
  padding: 10px 15px;
  background-color: rgba(239, 239, 239, 0.88);
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .bs-title-row {
    background-color: rgba(239, 239, 239, 0.65);
    -webkit-backdrop-filter: blur(14px) saturate(160%);
    backdrop-filter: blur(14px) saturate(160%);
  }
}
.bs-title-actions { display: flex; gap: 8px; }
.bs-title-row .bs-status { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.bs-desc { color: var(--muted); font-style: normal; font-size: 11px; }

.bs-row { display: flex; align-items: center; gap: 8px; }
.bs-num { color: var(--muted); flex-shrink: 0; }

.bs-name, .bs-desc-input, #bs-token {
  border: 1px solid #ddd;
  border-radius: 6px;
  padding: 6px 8px;
  font: inherit;
  color: var(--text);
  background-color: #fff;
  width: 100%;
  min-width: 0;
}
.bs-name {
  font-family: "Montserrat", "Open Sans", sans-serif;
  font-weight: 600;
  font-size: 12px;
  letter-spacing: 0.3px;
  color: var(--heading);
}
.bs-desc-input { font-size: 12px; }
.bs-num { font-family: "Montserrat", "Open Sans", sans-serif; font-size: 11px; }

/* Read-only look: plain text until the pencil enables editing */
.bs-item .bs-name, .bs-item .bs-desc-input {
  border-color: transparent;
  background-color: transparent;
  padding-left: 0;
  cursor: default;
  caret-color: var(--accent);
}
.bs-item .bs-desc-input { color: var(--muted); }
.bs-item .bs-desc-input::placeholder { color: transparent; }
.bs-item.is-editing .bs-desc-input::placeholder { color: #c4c4c4; }
.bs-item.is-editing .bs-name, .bs-item.is-editing .bs-desc-input { cursor: text; }
.bs-item.is-editing .bs-name:focus, .bs-item.is-editing .bs-desc-input:focus { outline: none; }
.bs-name:focus, .bs-desc-input:focus, #bs-token:focus { outline: 2px solid var(--link); border-color: transparent; }

.bs-save {
  border: 0;
  border-radius: 8px;
  padding: 9px 16px;
  font: inherit;
  font-weight: 600;
  color: #fff;
  background-color: var(--accent);
  cursor: pointer;
}
.bs-save:disabled { background-color: #c7c7c7; cursor: default; }
.bs-status { align-self: center; font-size: 11px; color: var(--muted); }
.bs-status.is-error { color: #c0392b; }

.bs-connect {
  background-color: var(--card-bg);
  border-left: 3px solid var(--accent);
  padding: 14px 16px;
  margin: 15px 0;
}
.bs-connect p { margin: 8px 0; }
.bs-disconnect { display: inline-block; margin-top: 20px; font-size: 11px; color: var(--muted); text-decoration: underline; }

.bs-pin-toggle { position: relative; cursor: pointer; }
.bs-pin-toggle input { position: absolute; opacity: 0; pointer-events: none; }
.bs-pin-toggle input:checked + .bs-icon { background-color: var(--accent); color: #fff; }

.bs-focus-editor {
  background-color: var(--card-bg);
  padding: 14px;
  margin: -6px 0 10px;
}
.bs-focus-hint { margin: 0 0 10px; color: var(--muted); }

.bs-focus-tools { display: flex; gap: 8px; margin-bottom: 10px; }
.bs-tab {
  border: 1px solid #d5d5d5;
  border-radius: 6px;
  background-color: #fff;
  padding: 5px 12px;
  font: inherit;
  font-size: 11px;
  color: var(--text);
  cursor: pointer;
}
.bs-tab.is-active { background-color: var(--heading); border-color: var(--heading); color: #fff; }
.bs-tab-center { margin-left: auto; }

.bs-focus-stage {
  position: relative;
  max-width: 460px;
  overflow: hidden;
  touch-action: none;
  user-select: none;
}
.bs-focus-stage img { width: 100%; display: block; pointer-events: none; }
.bs-frame {
  position: absolute;
  border: 2px solid #fff;
  border-radius: 3px;
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.55);
  cursor: move;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.bs-frame-shade {
  position: absolute;
  inset: 0;
  background-color: var(--hero-overlay);
  pointer-events: none;
}
.bs-frame-sig {
  position: relative;
  pointer-events: none;
  user-select: none;
}
/* corner grip: drag inwards to close in on the photo (down to 80%) */
.bs-frame-grip {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 26px;
  height: 26px;
  cursor: nwse-resize;
  touch-action: none;
}
.bs-frame-grip::after {
  content: '';
  position: absolute;
  right: 4px;
  bottom: 4px;
  width: 12px;
  height: 12px;
  border-right: 2px solid #fff;
  border-bottom: 2px solid #fff;
  border-bottom-right-radius: 3px;
}

.bs-focus-row { display: flex; align-items: flex-start; gap: 12px; }
.bs-center-btn { flex-shrink: 0; }
.bs-focus-previews figcaption { font-size: 10px; color: var(--muted); margin-top: 4px; }
.bs-prev { background-size: cover; border-radius: 4px; }
.bs-prev-land { width: 128px; height: 72px; }
.bs-prev-port { width: 44px; height: 81px; }

.bs-item-actions {
  margin-left: auto;
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

.bs-button {
  display: inline-block;
  background-color: var(--heading);
  color: #fff;
  padding: 8px 14px;
  border-radius: 4px;
  margin: 0 8px 8px 0;
  font-size: 12px;
}
.bs-button:hover { background-color: var(--link-hover); color: #fff; }

.bs-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 15px;
  background-color: var(--card-bg);
  padding: 10px;
  margin-bottom: 10px;
}
.bs-thumbs { display: flex; gap: 6px; flex-shrink: 0; align-items: center; }
.bs-thumb { background-size: cover; border-radius: 3px; display: block; cursor: zoom-in;
  outline: 2px solid transparent; outline-offset: 2px; transition: outline-color 0.15s ease-in-out; }
.bs-item.is-framing .bs-thumb { cursor: pointer; }
.bs-item.is-framing .bs-thumb.is-mode { outline-color: var(--accent); }
.bs-thumb { position: relative; }
.bs-thumb.is-off { filter: grayscale(1) brightness(0.72); }
.bs-thumb.is-off::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(to bottom left, transparent 45.5%, #fff 45.5%, #fff 54.5%, transparent 54.5%);
}
.bs-thumb-land { width: 118px; height: 66px; }
.bs-thumb-port { width: 36px; height: 66px; }
.bs-item-meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.bs-item-meta strong { font-weight: 600; word-break: break-all; }

.bs-notes { padding-left: 18px; margin: 0; }
.bs-notes li { margin-bottom: 6px; }

code {
  background-color: #e6e6e6;
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 12px;
}

/* ---------- Footer ---------- */

.site-footer {
  text-align: center;
  padding: 30px 15px 40px;
  color: var(--muted);
  font-size: 11px;
}
.site-footer a { color: var(--muted); text-decoration: underline; }

/* ---------- Scroll-up ---------- */

.scrollup {
  position: fixed;
  bottom: 30px;
  right: 30px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 0;
  background-color: #fff;
  color: var(--muted);
  cursor: pointer;
  display: none;
  align-items: center;
  justify-content: center;
  opacity: 0.85;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
  z-index: 100;
}
.scrollup.is-visible { display: flex; }
.scrollup svg { width: 16px; height: 16px; fill: currentColor; }

/* ---------- Responsive ---------- */

@media (max-width: 620px) {
  .hero-signature img, .hero-signature canvas { width: 118px; }
  .hero-copyright { bottom: calc(4px + env(safe-area-inset-bottom, 0px)); }
  .hero-caption { bottom: calc(22px + env(safe-area-inset-bottom, 0px)); }
  .bs-item { flex-wrap: wrap; }
  .bs-item-actions { margin-left: 0; }
  .hero-social { --soc-icon: 17px; column-gap: 26px; margin-top: 34px; }
  .social-inert svg { width: 17px; height: 17px; }
  .cr-full { display: none; }
  .cr-short { display: inline; font-size: 9px; }
  .bs-thumb-land { width: 92px; height: 52px; }
  .bs-thumb-port { width: 28px; height: 51px; }
  .bs-button { padding: 9px 12px; }
  .single-wrap .card-body { padding: 14px 16px 16px; }
}


/* ---------- "coming soon" (shop and archive) ---------- */

.soon {
  position: absolute;
  inset: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  /* dims whatever is behind it by 85% */
  background-color: rgba(0, 0, 0, 0.85);
  animation: soon-in 0.25s ease-out;
}
.soon[hidden] { display: none; }
.soon-sheet { position: relative; display: flex; align-items: center; }
.soon-text {
  margin: 0;
  font-family: "Caveat", "Segoe Script", cursive;
  font-weight: 500;
  /* 25pt larger than before (44px + 33px); the vw ceiling keeps the line
     from running off a narrow screen, since it never wraps */
  font-size: min(77px, 14vw);
  line-height: 1.1;
  color: #fff;
  text-transform: none;
  letter-spacing: 0.5px;
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.45);
}
.soon-close {
  position: absolute;
  top: -14px;
  right: -34px;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  background: transparent;
  color: #fff;
  opacity: 0.85;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.2s ease-in-out;
}
.soon-close:hover { opacity: 1; }
.soon-close svg { width: 18px; height: 18px; }
@keyframes soon-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
/* every way out of it fades rather than blinking off; pointer-events go
   first so the page is usable again the instant it is dismissed, rather
   than after the fade finishes */
.soon.is-going {
  animation: soon-out 0.3s ease-in forwards;
  pointer-events: none;
}
@keyframes soon-out {
  from { opacity: 1; }
  to { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .soon.is-going { animation: none; opacity: 0; }
}
@media (max-width: 700px) {
  .soon-text { font-size: min(69px, 15vw); }
  .soon-close { right: -28px; }
}
@media (prefers-reduced-motion: reduce) {
  .soon { animation: none; }
}