/* Someday Soon — the studio's own back office.
 *
 * Built for a phone first and widened from there, because it will mostly be
 * read standing up between clients. Three rules held throughout:
 *
 *   nothing may make the page scroll sideways — every long string wraps,
 *   every image is bounded, and there is not one fixed width in the file;
 *   nothing tappable is smaller than 44px;
 *   every input is at least 16px, because iOS zooms the whole page in on
 *   anything smaller and that zoom never quite goes away.
 *
 * The palette is their own sign theme: black ground, cream type, green as a
 * graphic colour and never as body text on black. */

:root {
  --black: #181818;
  --cream: #fff6db;
  --green: #03604b;

  /* The site's three grounds, and it uses all of them: black for the sign,
     cream for daylight, green for the studio page. Which one this page sits
     on is the single biggest thing about how it reads -- everything below is
     written against --ground and --type rather than against black. */
  /* Cards lift off the page; the page does not sink under them.
   *
   * The first attempt darkened the ground so cream cards could sit on it, and
   * darkening cream moves it toward yellow -- the page went khaki and the
   * background had been the good part. So the ground stays exactly the cream
   * it was, the cards go a shade brighter than it, and the separation comes
   * from an edge and a shadow rather than from making anything muddier.
   *
   * The rule worth keeping: to separate two things, add light to the one in
   * front before you take it from the one behind. */
  --ground: var(--cream);
  --card: #fffdf4;
  --type: var(--black);
  --ink: #f4e9cc;
  --edge: rgba(24, 24, 24, 0.15);
  --lift: 0 1px 3px rgba(24, 24, 24, 0.07), 0 6px 16px -10px rgba(24, 24, 24, 0.14);
  --line: rgba(24, 24, 24, 0.2);
  --soft: rgba(24, 24, 24, 0.66);
  --faint: rgba(24, 24, 24, 0.45);
  --fill: rgba(24, 24, 24, 0.04);
  /* What a photograph is mounted on. The site frames its photographs in the
     colour the page is not, so on cream that is the ink. */
  --frame: var(--black);
  /* Green reads as an alert colour on a cream page in a way it never does on
     black, so the two states are chosen against this ground, not inherited. */
  --bad: #b5342a;
  --good: #1c6b3f;
  --bad: #e0685f;
  --good: #7fb98f;
  --body: Manrope, ui-sans-serif, -apple-system, "Segoe UI", Roboto, sans-serif;
  color-scheme: light;
}

/* One typeface, and hierarchy from weight, size and space instead.
 *
 * Avenolas is not used anywhere on this page and should not be added back.
 * It is the studio's display face and it belongs on their site; this is a
 * thing read off a phone between clients, and every word on it is either
 * somebody's name, somebody's number or a control. The identity comes from
 * their own shopfront on the way in, and from the colour of the page. */
.stat .k, .field > span, .tabs button, .primary, .enq-tag,
.days button, .copy-item label, .copy-group > summary, .enq-actions .go,
.eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 600;
}

* { box-sizing: border-box; }

/* The browser's own rule for [hidden] is display:none, and any class that
   sets display beats it -- so .gate{display:grid} left both sign-in screens
   laid out and pushed the app 1,688px down the page. Anything toggled with
   .hidden in this file needs this to actually go away. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  /* The single most common cause of a sideways scroll is one long word in
     user-submitted text. Enquiries are full of them: pasted links, long
     email addresses, no spaces for forty characters. */
  overflow-wrap: anywhere;
}

body {
  margin: 0;
  background: var(--black);
  color: var(--cream);
  font: 17px/1.66 var(--body);
  letter-spacing: 0.005em;
  min-height: 100dvh;
}

img { max-width: 100%; height: auto; display: block; }
button, input, textarea, select { font: inherit; color: inherit; }

/* ---------- signing in ---------- */

.gate { display: grid; place-items: center; min-height: 100dvh; padding: 8vh 20px; }
.gate-inner { width: 100%; max-width: 26rem; }


.gate-sub {
  margin: 0 0 2.2rem;
  color: var(--soft);
  letter-spacing: 0.26em;
  font-size: 0.95rem;
}

.field { display: block; margin: 0 0 1rem; }
.field > span {
  display: block;
  font-size: 0.76rem;
  letter-spacing: 0.11em;
  color: var(--soft);
  margin-bottom: 0.45rem;
}
.field input, .field textarea {
  width: 100%;
  min-height: 48px;
  padding: 0.7rem 0.8rem;
  background: rgba(255, 246, 219, 0.06);
  border: 1px solid var(--line);
  border-radius: 0;
  font-size: 16px;
}
.field textarea { min-height: 88px; resize: vertical; line-height: 1.5; }
.field input:focus, .field textarea:focus {
  outline: 2px solid var(--cream);
  outline-offset: 1px;
}

/* The site's own button: a solid green rectangle with cream type. Square,
   because nothing on that site has a rounded corner. */
.primary {
  width: 100%;
  min-height: 52px;
  padding: 0.85rem 1rem;
  background: var(--green);
  color: var(--cream);
  border: 0;
  border-radius: 0;
  font-size: 0.86rem;
  cursor: pointer;
}
.primary:hover { background: #04735a; }
.primary:disabled { opacity: 0.55; }

.who-list { display: grid; gap: 0.6rem; }
.who-list button {
  min-height: 56px;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 0;
  color: var(--cream);
  text-align: left;
  padding: 0 1rem;
  font-size: 1.05rem;
  cursor: pointer;
}
.who-list button:hover { border-color: var(--cream); }

.error { color: var(--bad); font-size: 0.9rem; margin: 0.8rem 0 0; }
.hint { color: var(--faint); font-size: 0.82rem; margin: 0.5rem 0 0; line-height: 1.5; }

/* ---------- the app ---------- */

.top {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.75rem 1rem;
  padding-top: max(0.75rem, env(safe-area-inset-top));
  background: var(--black);
  border-bottom: 1px solid var(--line);
}
.top-brand {
  letter-spacing: 0.08em;
  font-size: 1.15rem;
  color: var(--cream);
  flex: 1;
  min-width: 0;
}
.who-chip {
  /* 44px like everything else. It is small and in the corner, which is
     exactly the sort of control that gets missed on a phone. */
  min-height: 44px;
  padding: 0 0.75rem;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 0;
  color: var(--soft);
  font-size: 0.8rem;
  cursor: pointer;
  white-space: nowrap;
}

main {
  padding: 1rem 1rem 6.5rem;
  max-width: 54rem;
  margin: 0 auto;
}

.lede { color: var(--soft); font-size: 0.9rem; margin-bottom: 0.9rem; }

.tools { margin-bottom: 1rem; }
.tools input {
  width: 100%;
  min-height: 48px;
  padding: 0.6rem 0.8rem;
  font-size: 16px;
  background: rgba(255, 246, 219, 0.06);
  border: 1px solid var(--line);
  border-radius: 0;
}

/* ---------- enquiries ---------- */

.enq {
  border: 1px solid var(--line);
  border-radius: 0;
  margin-bottom: 0.7rem;
  overflow: hidden;
}
.enq.done { opacity: 0.62; }
.enq-head {
  width: 100%;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.3rem 0.8rem;
  align-items: start;
  padding: 0.85rem 0.9rem;
  background: transparent;
  border: 0;
  text-align: left;
  cursor: pointer;
  min-height: 56px;
}
.enq-name { font-size: 1.12rem; font-weight: 700; letter-spacing: 0; }
.enq-meta { grid-column: 1 / -1; color: var(--faint); font-size: 0.8rem; }
.enq-when { color: var(--faint); font-size: 0.78rem; white-space: nowrap; }
.enq-tag {
  display: inline-block;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  border: 1px solid var(--line);
  border-radius: 0;
  padding: 0.1rem 0.5rem;
  margin-right: 0.35rem;
  color: var(--soft);
}
.enq-tag.spam { color: var(--bad); border-color: rgba(224, 104, 95, 0.4); }
.enq-tag.done { color: var(--good); border-color: rgba(127, 185, 143, 0.4); }

.enq-body { padding: 0 0.9rem 1rem; border-top: 1px solid var(--line); }
.enq-body h3 {
  font-size: 0.98rem;
  letter-spacing: 0.12em;
  color: var(--soft);
  margin: 1.1rem 0 0.4rem;
}
.enq-body p { margin: 0; white-space: pre-wrap; }
.kv { display: grid; grid-template-columns: 8.5rem 1fr; gap: 0.2rem 0.8rem; margin-top: 0.9rem; }
.kv dt { color: var(--faint); font-size: 0.84rem; }
.kv dd { margin: 0; font-size: 0.92rem; }
.kv a { color: var(--cream); }

.shots {
  display: grid;
  gap: 0.5rem;
  grid-template-columns: repeat(auto-fill, minmax(min(9rem, 100%), 1fr));
  margin-top: 0.5rem;
}
.shots img { border-radius: 0; border: 1px solid var(--line); }

.enq-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1rem; }
.enq-actions a, .enq-actions button {
  flex: 1 1 10rem;
  min-height: 46px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 0;
  background: transparent;
  color: var(--cream);
  text-decoration: none;
  font-size: 0.92rem;
  cursor: pointer;
  padding: 0 0.8rem;
}
.enq-actions .go { background: var(--green); color: var(--cream); border-color: var(--green); }

/* ---------- visitors ---------- */

.stats {
  display: grid;
  gap: 0.6rem;
  grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr));
  margin-bottom: 1.4rem;
}
.stat { border: 1px solid var(--line); border-radius: 0; padding: 0.85rem 0.9rem; }
.stat .k { font-size: 0.74rem; letter-spacing: 0.11em; color: var(--soft); }
/* The numbers are the point of that panel, so they take heading size. Light
   weight and tight tracking: at this size that reads as confidence, where
   bold reads as a spreadsheet. */
.stat .v {
  font-size: 2.5rem; line-height: 1.05; font-weight: 300;
  margin-top: 0.25rem; letter-spacing: -0.02em;
}
.stat .s { font-size: 0.8rem; color: var(--faint); }

/* .card is gone. It was the last bordered box, and its heading was painted
   var(--cream) -- cream type on the cream page, so the title was rendered,
   took up its space, and could not be seen. That is the same fault as the
   tab bar earlier: a colour hard-coded to one ground on a page that has
   three. Nothing here should name --cream or --black directly; use --type
   and --ground, which follow the page. */

.rows { display: grid; gap: 0.45rem; }
.row { display: grid; grid-template-columns: 1fr auto; gap: 0.2rem 0.7rem; align-items: center; }
.row .l { min-width: 0; font-size: 0.92rem; }
.row .n { font-variant-numeric: tabular-nums; color: var(--soft); font-size: 0.88rem; }
.row .bar { grid-column: 1 / -1; height: 4px; border-radius: 0; background: rgba(255,246,219,0.12); }
.row .bar i { display: block; height: 100%; border-radius: 0; background: var(--green); }

/* ---------- your site ---------- */

.days { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.8rem 0; }
.days button {
  min-height: 46px; min-width: 46px; padding: 0 0.75rem;
  border: 1px solid var(--line); border-radius: 0;
  background: transparent; color: var(--soft); cursor: pointer;
  font-size: 0.78rem; letter-spacing: 0.07em;
}
.days button[aria-pressed="true"] {
  background: var(--green); color: var(--cream); border-color: var(--green);
}
.times { display: grid; gap: 0.8rem; grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr)); }
.times .field { margin: 0; }

.switch { display: flex; align-items: center; gap: 0.7rem; min-height: 48px; cursor: pointer; }
.switch input { width: 26px; height: 26px; accent-color: var(--cream); }
/* The box itself is under 44px and deliberately so: it sits inside a label
   that is 48px tall and the whole row toggles it, so the tap target is the
   row, not the square. */

.copy-group { margin-top: 1rem; }
.copy-group > h3 {
  font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--faint); margin: 0 0 0.5rem;
}
.copy-item { margin-bottom: 0.9rem; }
.copy-item label {
  display: block; font-size: 0.74rem; letter-spacing: 0.09em;
  color: var(--soft); margin-bottom: 0.4rem;
}
.copy-item textarea {
  width: 100%; min-height: 74px; padding: 0.6rem 0.7rem; font-size: 16px;
  background: rgba(255, 246, 219, 0.06); border: 1px solid var(--line);
  border-radius: 0; line-height: 1.5; resize: vertical;
}
.copy-item.changed textarea { border-color: var(--cream); }

/* Sticks above the tab bar, not under it. The tabs are fixed and 56px tall
   plus the home indicator, so a save bar at bottom:0 puts the only button
   that matters underneath them. */
.save-bar {
  position: sticky;
  bottom: calc(56px + env(safe-area-inset-bottom));
  padding: 0.8rem 0 0.6rem;
  background: var(--black);
}

.publish {
  border: 1px solid var(--line); border-left-width: 3px;
  border-radius: 0; padding: 0.7rem 0.85rem; margin-bottom: 1rem; font-size: 0.9rem;
}
.publish.running { border-left-color: var(--cream); }
.publish.done { border-left-color: var(--good); }
.publish.failed, .publish.waiting { border-left-color: var(--bad); }

/* ---------- tabs ---------- */

.tabs {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 6;
  display: grid; grid-template-columns: repeat(3, 1fr);
  background: var(--ink); border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom);
}
.tabs button {
  min-height: 58px; background: transparent; border: 0; color: var(--faint);
  font-size: 0.78rem; letter-spacing: 0.1em; cursor: pointer; padding: 0 0.3rem;
}
.tabs button.active { color: var(--cream); box-shadow: inset 0 2px 0 var(--cream); }

.empty { color: var(--faint); padding: 1.4rem 0; text-align: center; }

.toast {
  position: fixed; left: 1rem; right: 1rem; bottom: calc(72px + env(safe-area-inset-bottom));
  z-index: 9; background: var(--cream); color: var(--black);
  border-radius: 0; padding: 0.75rem 0.9rem; font-size: 0.92rem;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.45);
}
.toast.bad { background: var(--bad); color: #fff; }

/* Wider screens get the same layout with more air, and the tab bar moves up
   out of the thumb zone it no longer needs to be in. */
@media (min-width: 46rem) {
  main { padding: 1.6rem 1.6rem 6rem; }
  .kv { grid-template-columns: 10rem 1fr; }
  .toast { left: auto; right: 1.6rem; max-width: 26rem; }
}

@media (prefers-reduced-motion: no-preference) {
  .enq-body { animation: reveal 0.16s ease-out; }
  @keyframes reveal { from { opacity: 0; } to { opacity: 1; } }
}

/* Copy sections fold shut. 139 text boxes in one list is a wall on a phone,
   and every one of them is layout the browser does for nothing. */
.copy-group { border-top: 1px solid var(--line); }
.copy-group > summary {
  display: flex; align-items: center; justify-content: space-between; gap: 0.8rem;
  min-height: 54px; cursor: pointer; list-style: none;
  font-size: 0.82rem; letter-spacing: 0.09em;
}
.copy-group > summary::-webkit-details-marker { display: none; }
.copy-group > summary::after { content: "+"; font-size: 1.2rem; color: var(--faint); }
.copy-group[open] > summary::after { content: "–"; }
.copy-group > summary .count {
  margin-left: auto; margin-right: 0.4rem; font-size: 0.76rem; color: var(--faint);
}
.copy-group[open] { padding-bottom: 0.6rem; }


/* ---------- the site's own page furniture ----------
 *
 * Their pages have no boxes on them. An eyebrow, an enormous heading, a
 * paragraph, and space -- separation comes from rhythm and the odd hairline,
 * never from a border drawn round everything. Bordered rectangles are what
 * made this read as an admin panel wearing their colours rather than as part
 * of their site, so the cards are gone.
 */

.eyebrow {
  font-size: 0.95rem;
  letter-spacing: 0.12em;
  color: var(--soft);
  margin: 0.6rem 0 0.35rem;
}

.head {
  
  text-transform: uppercase;
  font-size: clamp(2.6rem, 13vw, 3.6rem);
  line-height: 0.94;
  letter-spacing: 0.01em;
  color: var(--cream);
  margin: 0 0 1.1rem;
  font-weight: 400;
}

/* A section is a rule and some air. */
.block {
  display: block;
  border: 0;
  border-top: 1px solid var(--line);
  padding: 1.6rem 0 0.4rem;
  margin: 0 0 1.6rem;
}
.block h2 {
  font-size: 1.5rem;
  letter-spacing: 0.05em;
  margin: 0 0 0.5rem;
  font-weight: 400;
}

/* Enquiries: a list separated by hairlines, not a stack of boxes. */
.enq {
  border: 0;
  border-top: 1px solid var(--line);
  border-radius: 0;
  margin: 0;
}
.enq:last-child { border-bottom: 1px solid var(--line); }
.enq-head { padding: 1.05rem 0; min-height: 64px; }
.enq-body { padding: 0 0 1.4rem; border-top: 0; }

/* Tags read as small type with a rule under them rather than pills. */
.enq-tag {
  border: 0;
  padding: 0;
  margin-right: 0.9rem;
  color: var(--faint);
}
.enq-tag.spam { color: var(--bad); }
.enq-tag.done { color: var(--good); }

/* Figures without frames; the number carries it. */
.stat { border: 0; padding: 0.2rem 0 1rem; }
.stat .v { font-size: 3.1rem; }
.stats { gap: 0.4rem 1.6rem; margin-bottom: 0.6rem; }

/* Their photographs get the cream mount the site gives them. */
.shots a {
  display: block;
  background: var(--frame);
  padding: 6px;
}
.shots img { border: 0; border-radius: 0; }

/* The site's two actions: a solid rectangle, and a link with a rule under it. */
.enq-actions .go {
  background: var(--green);
  color: var(--cream);
  border: 0;
  font-size: 0.86rem;
}
.enq-actions button:not(.go) {
  border: 0;
  border-bottom: 1px solid var(--line);
  color: var(--soft);
  justify-content: flex-start;
}

/* Inputs sit on a rule rather than in a box, as the site's own form does. */
.field input, .field textarea, .tools input, .copy-item textarea {
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line);
  padding-left: 0;
  padding-right: 0;
}
.field input:focus, .field textarea:focus,
.tools input:focus, .copy-item textarea:focus {
  outline: 0;
  border-bottom-color: var(--cream);
}

.copy-group { border-top: 1px solid var(--line); }
.copy-group:last-of-type { border-bottom: 1px solid var(--line); }

.publish { border: 0; border-left: 3px solid var(--line); padding-left: 0.9rem; }

/* The top bar is the site's: black, wordmark left, a bordered square right. */
.who-chip {
  border: 1px solid var(--line);
  border-radius: 0;
  min-width: 44px;
  color: var(--cream);
  font-family: var(--body);
}


/* The save bar sits over whatever is scrolling under it, so it needs an edge
   -- without one it reads as content overlapping content rather than as a bar
   deliberately held above the page. */
.save-bar {
  border-top: 1px solid var(--line);
  box-shadow: 0 -14px 18px -8px var(--black);
}
/* And the panel needs room underneath so nothing is permanently trapped
   behind it at the bottom of the scroll. */
#panel-site { padding-bottom: 3.5rem; }


/* ---------- the three grounds ----------
   Named after the site's own themes. Set on <body> so one attribute changes
   the whole page, the way the site's palette switcher used to. */

/* The other two grounds stay reachable with ?theme=, because the studio may
   want the shop's own look back and it costs nothing to keep. */
body[data-theme="sign"] { color-scheme: dark;
  --ground: #0f0f0f;
  --card: var(--black);
  --edge: rgba(255, 246, 219, 0.14);
  --lift: none;
  --type: var(--cream);
  --ink: #0f0f0f;
  --line: rgba(255, 246, 219, 0.16);
  --soft: rgba(255, 246, 219, 0.62);
  --faint: rgba(255, 246, 219, 0.38);
  --fill: rgba(255, 246, 219, 0.06);
  --frame: var(--cream);
  --bad: #e0685f;
  --good: #7fb98f;
}
body[data-theme="ivy"] { color-scheme: dark;
  --ground: #024537;
  --card: var(--green);
  --edge: rgba(255, 246, 219, 0.18);
  --lift: none;
  --type: var(--cream);
  --ink: #024537;
  --line: rgba(255, 246, 219, 0.24);
  --soft: rgba(255, 246, 219, 0.74);
  --faint: rgba(255, 246, 219, 0.5);
  --fill: rgba(255, 246, 219, 0.07);
  --frame: var(--cream);
  --bad: #ffb4ad;
  --good: #bfe6c9;
}

body { background: var(--ground); color: var(--type); }
.top { background: var(--ground); }
.save-bar { background: var(--ground); box-shadow: 0 -14px 18px -8px var(--ground); }
.tabs { background: var(--ink); }
.wordmark, .head, .top-brand, .block h2, .enq-name, .stat .v,
.copy-group > summary, .who-chip { color: var(--type); }
.eyebrow, .gate-sub, .field > span, .hint, .stat .k, .enq-when,
.enq-tag, .lede, .copy-item label { color: var(--soft); }
.field input, .field textarea, .tools input, .copy-item textarea,
.who-list button, .days button, .enq-actions button { color: var(--type); }
.kv a { color: var(--type); }
.row .bar { background: var(--fill); }

/* On cream, the sign's colours swap: green type, cream face behind it. */
.toast { background: var(--black); color: var(--cream); }
body[data-theme="sign"] .toast { background: var(--cream); color: var(--black); }

/* On green, the solid button is cream with green type, as on the studio page. */
body[data-theme="ivy"] .wordmark { color: var(--cream); text-shadow: 3px 3px 0 rgba(2,49,38,0.85); }
body[data-theme="ivy"] .primary { background: var(--cream); color: var(--green); }
body[data-theme="ivy"] .primary:hover { background: #fffdf2; }
body[data-theme="ivy"] .days button[aria-pressed="true"] { background: var(--cream); color: var(--green); border-color: var(--cream); }
body[data-theme="ivy"] .enq-actions .go { background: var(--cream); color: var(--green); }

/* The grain. Their pages look printed rather than rendered, and this is most
   of why: a fixed sheet of noise over everything, never scrolling with it. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  /* Over everything, chrome included. Sitting below the header and the tab
     bar left those two brighter than the page they float over, which read as
     a rendering fault rather than as a design. It passes pointer events
     through, so being on top costs nothing. */
  z-index: 200;
  pointer-events: none;
  background-image: url("/font/grain.png");
  background-size: 220px 220px;
  /* Lighter still now that the page has two papers: multiplied over the
     cards it was darkening the very contrast that separates them from the
     ground, which is the whole point of having two. Enough to feel like
     paper, not enough to close the gap. */
  opacity: 0.14;
  mix-blend-mode: multiply;
}
body[data-theme="sign"]::after,
body[data-theme="ivy"]::after { opacity: 0.5; mix-blend-mode: overlay; }

/* The active tab takes the ground's own type colour, whichever ground it is.
   Hard-coding cream left it near-invisible on the green. */
.tabs button.active { color: var(--type); box-shadow: inset 0 2px 0 var(--type); }
.tabs button { color: var(--faint); }


/* ---------- what carries it now ----------
 *
 * With the display face gone, the page has to be stylish some other way, and
 * the studio have better material than a typeface: their own shopfront, their
 * mark, and three flat colours that look expensive when you commit to them.
 */

/* The way in. Their sign, full bleed, with the form sitting on it -- the
   painted lettering does the branding so nothing here has to imitate it. */
.gate {
  position: relative;
  display: block;
  background: var(--black);
  padding: 0;
  min-height: 100dvh;
}
/* The whole photograph, at its own proportions, with the page fading out of
   the bottom of it. Cropping it to fill the screen cut the sign in half, and
   the sign is the only part that has to survive.
   The fade is a child of the photograph rather than positioned against the
   viewport: sized in vw it landed short of the bottom edge on some screens
   and past it on others, which showed as a hard seam. */
.gate-photo { position: relative; display: block; }
.gate-photo img { display: block; width: 100%; height: auto; }
.gate-photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom,
    rgba(24, 24, 24, 0) 35%, rgba(24, 24, 24, 0.55) 72%, var(--black) 100%);
  pointer-events: none;
}
.gate-inner {
  position: relative;
  z-index: 1;
  max-width: none;
  /* Pulled up over the fade so the form starts inside the photograph rather
     than in a separate black box under it. */
  margin-top: -3.2rem;
  padding: 0 1.4rem calc(2.6rem + env(safe-area-inset-bottom));
  color: var(--cream);
}
.gate .mark {
  display: block;
  width: 54px;
  height: 54px;
  margin-bottom: 1.1rem;
  background: var(--cream);
  -webkit-mask: url("/font/mark.png") center / contain no-repeat;
  mask: url("/font/mark.png") center / contain no-repeat;
}
.gate h1 {
  font-size: clamp(2.1rem, 9.5vw, 3rem);
  line-height: 1.02;
  letter-spacing: -0.035em;
  font-weight: 200;
  margin: 0 0 0.4rem;
  color: var(--cream);
}
.gate .gate-sub {
  color: rgba(255, 246, 219, 0.66);
  font-size: 0.76rem;
  letter-spacing: 0.24em;
  font-weight: 600;
  margin: 0 0 2rem;
}
.gate .field > span { color: rgba(255, 246, 219, 0.7); }
.gate .field input {
  color: var(--cream);
  border-bottom-color: rgba(255, 246, 219, 0.4);
  font-size: 17px;
}
.gate .field input:focus { border-bottom-color: var(--cream); }
.gate .primary { background: var(--cream); color: var(--black); }
.gate .who-list button {
  border: 0;
  border-bottom: 1px solid rgba(255, 246, 219, 0.28);
  color: var(--cream);
  font-size: 1.15rem;
  padding: 0;
  min-height: 60px;
}
.gate .hint { color: rgba(255, 246, 219, 0.55); }

/* Headings: light and large, tracked in rather than out. One typeface can
   still be a voice if you use the whole of it. */
.head {
  font-size: clamp(2.4rem, 11.5vw, 3.2rem);
  line-height: 0.98;
  letter-spacing: -0.04em;
  font-weight: 200;
  margin: 0 0 1.2rem;
}
.eyebrow { font-size: 0.7rem; color: var(--green); margin: 0.4rem 0 0.5rem; }
.block h2 { font-size: 1.35rem; font-weight: 300; letter-spacing: -0.02em; }
.stat .v { font-weight: 200; letter-spacing: -0.03em; }

/* One green field, where the numbers are. Their site changes the ground
   between pages; this does it between sections, which stops a cream page
   reading as a blank document. */
#panel-visitors .stats {
  background: var(--green);
  color: var(--cream);
  margin: 0 -1rem 1.6rem;
  padding: 1.4rem 1rem 1rem;
  gap: 0.4rem 1.6rem;
}
#panel-visitors .stat { padding: 0 0 0.9rem; }
#panel-visitors .stat .k { color: rgba(255, 246, 219, 0.7); }
#panel-visitors .stat .v, #panel-visitors .stat .s { color: var(--cream); }
#panel-visitors .stat .s { opacity: 0.75; }

/* The tab bar is the sign: black, always, whatever the page is standing on.
   It anchors the bottom of a pale screen the way the header anchors the top
   of theirs. */
.tabs { background: var(--black); }
.tabs button { color: rgba(255, 246, 219, 0.5); }
.tabs button.active { color: var(--cream); box-shadow: inset 0 2px 0 var(--cream); }

/* Photographs get the mount and the caption the site gives them. */
.shots a { position: relative; background: var(--black); padding: 7px; }

/* The top bar carries the mark rather than a wordmark set in type. */
.top-brand { display: flex; align-items: center; gap: 0.6rem; font-size: 0.95rem;
             font-weight: 600; letter-spacing: 0.02em; text-transform: none; }
.top-brand .mark {
  width: 26px; height: 26px; flex: none;
  background: var(--type);
  -webkit-mask: url("/font/mark.png") center / contain no-repeat;
  mask: url("/font/mark.png") center / contain no-repeat;
}

/* ---------- books, notes and replies ---------- */

.books { display: grid; gap: 0.5rem; margin-top: 0.9rem; }
.book {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  min-height: 56px; padding: 0 0.9rem;
  background: transparent; border: 1px solid var(--line); border-radius: 0;
  color: var(--type); cursor: pointer; text-align: left;
}
.book-name { font-size: 1.05rem; }
.book-state {
  font-size: 0.7rem; letter-spacing: 0.1em; text-transform: uppercase;
  font-weight: 600; color: var(--faint);
}
/* Open is the resting state and gets no colour; shut is the exception and is
   the only one worth drawing the eye to. */
.book:not(.open) { border-color: var(--green); }
.book:not(.open) .book-state { color: var(--green); }

.notes { margin-top: 1.4rem; }
.notes textarea {
  width: 100%; min-height: 84px; padding: 0.6rem 0; font-size: 16px;
  background: transparent; border: 0; border-bottom: 1px solid var(--line);
  line-height: 1.55; resize: vertical; color: var(--type);
}
.notes textarea:focus { outline: 0; border-bottom-color: var(--type); }
.note-list { display: grid; gap: 0.9rem; margin-bottom: 1.2rem; }
.note { border-left: 2px solid var(--line); padding-left: 0.8rem; }
/* A note that was actually sent to the enquirer is a different kind of fact
   from one left for each other, and reads as one. */
.note.sent { border-left-color: var(--green); }
.note-who {
  display: flex; gap: 0.5rem; font-size: 0.7rem; letter-spacing: 0.1em;
  text-transform: uppercase; font-weight: 600; color: var(--faint);
  margin-bottom: 0.25rem;
}
.note.sent .note-who { color: var(--green); }
.note p { margin: 0; white-space: pre-wrap; font-size: 0.94rem; }


/* ---------- lifting the content off the page ----------
 *
 * Everything a person reads or acts on sits on a card: a step of paper, a
 * hairline and a shade of lift. The hairlines that used to divide a flat page
 * are gone from inside the cards -- one separator is enough, and two is what
 * made it feel busy while still being hard to scan. */

.block, .enq, .tools input, .publish {
  background: var(--card);
  border: 1px solid var(--edge);
  box-shadow: var(--lift);
}

.block {
  padding: 1.3rem 1.05rem 1.1rem;
  margin: 0 0 0.9rem;
  border-radius: 3px;
}
.block h2 { margin-bottom: 0.35rem; }

/* Enquiries become cards rather than rows on a rule. Each one is a thing you
   act on, so each one gets its own edge. */
.enq {
  border-radius: 3px;
  margin: 0 0 0.65rem;
  overflow: hidden;
}
.enq:last-child { border-bottom: 1px solid var(--edge); }
.enq-head { padding: 0.95rem 0.95rem; }
.enq-body { padding: 0 0.95rem 1.2rem; border-top: 1px solid var(--edge); padding-top: 0.9rem; }

.tools input {
  padding: 0.75rem 0.9rem;
  border-radius: 3px;
  border-bottom-width: 1px;
}
.tools input:focus { border-color: var(--type); }

.publish { border-radius: 3px; border-left: 3px solid var(--line); }

/* Fields inside a card sit on a rule again -- a box inside a box is where
   this starts looking like a form from 2006. */
.block .field input, .block .field textarea, .copy-item textarea {
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--edge);
}

/* The copy sections divide inside their card, so they keep hairlines. */
.copy-group { border-top: 1px solid var(--edge); }
.copy-group:last-of-type { border-bottom: 0; }

/* The visitor figures keep their green field, and it now runs to the edges of
   its card rather than the edges of the screen. */
#panel-visitors .stats {
  margin: 0 0 0.9rem;
  border-radius: 3px;
  padding: 1.3rem 1.05rem 0.9rem;
}

/* A little more air everywhere, which is most of what "easier on the eyes"
   actually means. */
body { font-size: 17px; line-height: 1.68; }
main { padding: 1.1rem 0.85rem 7rem; }
.head { margin-bottom: 1rem; }
.kv { gap: 0.35rem 0.8rem; }
.kv dd { font-size: 0.95rem; }
.enq-body p { font-size: 0.97rem; }


/* ---------- stacking ----------
 *
 * Three layers, and only three: content on the page, chrome over content, the
 * grain over both.
 *
 * Lifting the *cards* instead -- which is what I tried first -- put scrolling
 * content over the fixed header and the tab bar and made it swallow taps
 * meant for them. Content never leaves the page.
 */
.top { z-index: 105; }
.save-bar { z-index: 104; }
.tabs { z-index: 106; }
.toast { z-index: 110; }

/* ---------- the letter ----------
 *
 * What the person on the other end actually opens, wrapper and all. The
 * greeting and the signature are drawn quiet and the studio's own words at
 * full strength, so at a glance it reads as "this is the bit that is mine".
 *
 * Given the shape of a printed note rather than a form field: its own paper,
 * a rule at the top carrying the subject line, and room around the words. It
 * is the one thing on this page that is a picture of something rather than a
 * control, and it should look like it. */

.letter {
  margin: 1.1rem 0 0.4rem;
  background: var(--card);
  border: 1px solid var(--edge);
  box-shadow: var(--lift);
  border-radius: 3px;
  overflow: hidden;
}

.letter-head {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--edge);
  background: rgba(24, 24, 24, 0.025);
}
.letter-head > span:first-child {
  font-size: 0.64rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--faint);
}
.letter-subject { font-size: 0.9rem; font-weight: 600; }

.letter-body { padding: 1.1rem 0.95rem 1.2rem; }
.letter-body p { margin: 0 0 0.9rem; font-size: 0.96rem; line-height: 1.62; }
.letter-body p:last-child { margin-bottom: 0; }

/* Theirs, at full strength. */
.letter-written { white-space: pre-wrap; }

/* Ours: the greeting, the name, the address. Present, clearly not the part
   they are writing, and never mistaken for it. */
.letter .quiet { color: var(--faint); }
.letter .quiet + .quiet { margin-top: -0.6rem; }

.letter .hint { padding: 0 0.95rem 0.9rem; margin: 0; }
