/* One stylesheet, no framework. Plain and a little old-fashioned on purpose. */

:root {
  --paper: #f7f5f0;
  --ink: #16150f;
  --muted: #6b675c;
  --rule: #cec9bd;
  --accent: #7a2e1f;
}

* { box-sizing: border-box; }

html { font-size: 17px; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  color: var(--ink);
  font-family: Georgia, "Iowan Old Style", "Times New Roman", serif;
  line-height: 1.55;
}

body > * { position: relative; z-index: 1; }

/* The globe. Landing page only, and behind everything: it used to be a
   background image, and it keeps that image's position exactly — the
   percentages below are the same ones background-position was using, which is
   why they are written as a percentage offset against a matching translate.

   It is a drawing, not a control, so it takes no clicks and no focus. */
.globe-stage {
  position: fixed;
  inset: 0;
  /* Behind its siblings, which are in normal flow and would otherwise be
     painted under it. #app has no background of its own, so this puts the
     globe between the paper and the words, which is where it was before. */
  z-index: -1;
  pointer-events: none;
}

.globe {
  position: absolute;
  left: 50%;
  top: 44%;
  width: min(78vh, 620px);
  height: auto;
  transform: translate(-50%, -44%);

  /* Faint, because the form sits on top of it at this width. Not so faint that
     the two countries stop being readable — showing them is the whole job. */
  opacity: 0.38;
}

.globe-sphere,
.globe-graticule,
.globe-arc { fill: none; }

.globe-sphere { stroke: var(--rule); }

.globe-graticule {
  stroke: var(--rule);
  stroke-width: 0.75;
  opacity: 0.75;
}

.globe-land {
  fill: var(--rule);
  opacity: 0.45;
  stroke: none;
}

.globe-country {
  fill: var(--accent);
  opacity: 0.9;
  stroke: none;
}

.globe-arc {
  stroke: var(--accent);
  stroke-width: 1.75;
  stroke-linecap: round;
}

/* The disc can be taken hold of and turned. It is the one part of the globe
   that takes pointer events — the stage around it does not, so the form can
   still be used where the two overlap.

   touch-action stops a drag across the globe from scrolling the page instead
   of turning it. */
.globe-grab {
  fill: none;
  pointer-events: all;
  cursor: grab;
  touch-action: none;
}

.globe-grab.held { cursor: grabbing; }

/* A ring rather than a dot: it marks the end of the line without covering the
   country underneath, and it is the only thing that shows at all when the
   country is one Natural Earth can barely draw — Singapore, Malta, Monaco. */
.globe-mark {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.25;
}

main {
  flex: 1;
  width: 100%;
  max-width: 34rem;
  margin: 0 auto;
  padding: 4.5rem 1.5rem 3rem;
}

/* The landing page is short; sitting it on the globe's centre line reads
   better than leaving a band of empty paper underneath. */
body.home main {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-top: 2rem;
  padding-bottom: 4rem;
}

/* Wide screens: the globe keeps the left half of the page, the form takes
   the right. Narrower than this, there isn't room for both side by side, so
   the form stays centred over the globe as above. */
@media (min-width: 860px) {
  /* Nothing is on top of it here, so it can be seen properly. */
  .globe {
    left: 24%;
    top: 50%;
    width: min(74vh, 580px);
    transform: translate(-24%, -50%);
    opacity: 0.8;
  }

  body.home main {
    margin-left: auto;
    margin-right: max(5vw, 2.5rem);
  }
}

/* A heading with its own escape hatch beside it. Baseline-aligned so the
   button sits on the same line as the title, and wrapping under it rather
   than squeezing the heading once the row runs out of width. */
.page-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.2rem 1.4rem;
}

.page-head h1 { margin-bottom: 0; }
.page-head + .lede { margin-top: 0.6rem; }

h1 {
  font-size: 2.1rem;
  font-weight: normal;
  line-height: 1.15;
  margin: 0 0 0.6rem;
  letter-spacing: -0.01em;
}

h2 {
  font-size: 1.2rem;
  font-weight: normal;
  margin: 2rem 0 0.5rem;
}

p { margin: 0 0 1rem; }

.lede { color: var(--muted); margin-bottom: 2.2rem; }

.muted { color: var(--muted); }

.small { font-size: 0.86rem; }

a { color: var(--accent); }

hr {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: 2rem 0;
}

/* ---- forms ---- */

form { margin: 0; }

.field { margin-bottom: 1.4rem; }

label {
  display: block;
  font-family: -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.35rem;
}

input[type="text"],
input[type="email"] {
  width: 100%;
  padding: 0.6rem 0.65rem;
  font-family: inherit;
  font-size: 1.05rem;
  color: var(--ink);
  background: #fffdf8;
  border: 1px solid var(--rule);
  border-radius: 0;
  outline-offset: 2px;
}

input:focus { border-color: var(--ink); outline: 1px solid var(--ink); }

input.code {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 1.5rem;
  letter-spacing: 0.4em;
  max-width: 11rem;
}

button, .button {
  display: inline-block;
  padding: 0.55rem 1.5rem;
  font-family: inherit;
  font-size: 1rem;
  color: var(--paper);
  background: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 0;
  cursor: pointer;
  text-decoration: none;
}

button:hover, .button:hover { background: #000; }

/* Also matches a link wearing .button, for actions that change nothing and are
   therefore a plain href rather than a form post. */
button.quiet, .button.quiet {
  color: var(--ink);
  background: transparent;
  padding: 0.35rem 0.9rem;
  font-size: 0.86rem;
}

button.quiet:hover, .button.quiet:hover { background: rgba(0, 0, 0, 0.05); }

.actions { display: flex; align-items: baseline; gap: 1.2rem; flex-wrap: wrap; }

/* A decision rather than one action with a footnote: both buttons are real
   answers, so declining is a button too — quieter, but the same size target,
   and it keeps its own line once the row runs out of width. */
.actions.choose { margin-top: 1.6rem; align-items: center; gap: 0.9rem 1.2rem; }
.actions.choose button.quiet { border-color: var(--rule); color: var(--muted); }
.actions.choose button.quiet:hover { color: var(--ink); }

.page-head .button.quiet { border-color: var(--rule); color: var(--muted); }
.page-head .button.quiet:hover { color: var(--ink); }

.error {
  border-left: 3px solid var(--accent);
  padding: 0.15rem 0 0.15rem 0.75rem;
  margin-bottom: 1.4rem;
  color: var(--accent);
}

.notice {
  border-left: 3px solid var(--rule);
  padding: 0.15rem 0 0.15rem 0.75rem;
  margin-bottom: 1.4rem;
  color: var(--muted);
}

/* ---- order pages ---- */

.wide { max-width: 52rem; }

/* Spacing around the PDF viewer. Classes rather than style attributes so the
   Content-Security-Policy can forbid inline styles outright. */
.viewer-actions { margin-bottom: 1.2rem; }
.viewer-note { margin-top: 1rem; }

.viewer {
  width: 100%;
  height: 78vh;
  min-height: 420px;
  border: 1px solid var(--rule);
  background: #fffdf8;
}

dl.summary { margin: 0 0 1.5rem; }
dl.summary dt {
  font-family: -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}
dl.summary dd { margin: 0 0 0.8rem; }

/* ---- brand bar ---- */

.brand-bar {
  width: 100%;
  max-width: 34rem;
  margin: 0 auto;
  padding: 1.25rem 1.5rem 0;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink);
  text-decoration: none;
}

.brand img {
  display: block;
  border-radius: 6px;
}

/* ---- footer ---- */

footer {
  max-width: 34rem;
  width: 100%;
  margin: 0 auto;
  padding: 1.5rem;
  border-top: 1px solid var(--rule);
  font-size: 0.82rem;
  color: var(--muted);
}

footer a { color: var(--muted); }

/* The withdrawal-consent tick. Given room and a rule above it so it reads as
   a thing being agreed to, not a preference tucked beside the button. */
label.switch.consent {
  margin: 1.8rem 0 1.4rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--rule);
}

label.switch.consent em {
  display: block;
  margin-top: 0.3rem;
  line-height: 1.5;
}

label.switch.consent.has-error { color: var(--accent); }

@media (max-width: 480px) {
  html { font-size: 16px; }
  main { padding-top: 3rem; }
  h1 { font-size: 1.8rem; }
}

/* ---- app shell ----
   The Vue app owns a single root element, so it takes over the column layout
   that used to sit directly on <body>. */

#app {
  flex: 1;
  display: flex;
  flex-direction: column;
  width: 100%;
}

/* ---- field status line ----
   Every field keeps a line under it, whether or not it has anything to say, so
   an error appearing does not shove the rest of the form down the page. */

.field-status {
  margin: 0.3rem 0 0;
  min-height: 1.15rem;
  line-height: 1.15rem;
}

.error-text { color: var(--accent); }

.confirmed { color: var(--muted); }
.confirmed::before {
  content: "✓";
  margin-right: 0.35em;
  color: var(--ink);
}

.field.has-error input[type="text"],
.field.has-error input[type="email"],
.field.has-error input[type="date"],
.field.has-error input[type="number"] {
  border-color: var(--accent);
}

.optional {
  font-size: 0.85em;
  letter-spacing: 0.08em;
  opacity: 0.7;
}

/* ---- the place picker ---- */

.place-field { margin-bottom: 1rem; }

.combo { position: relative; }

.options {
  position: absolute;
  z-index: 20;
  top: calc(100% - 1px);
  left: 0;
  right: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  max-height: 17rem;
  overflow-y: auto;
  background: #fffdf8;
  border: 1px solid var(--ink);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
}

.options li {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.45rem 0.65rem;
  cursor: pointer;
  border-bottom: 1px solid var(--rule);
}

.options li:last-child { border-bottom: 0; }

.options li.active { background: var(--ink); color: var(--paper); }

.option-name { font-size: 1rem; }

/* The qualifier is the whole point of the row when two names collide, so it
   stays legible rather than fading into the background. */
.option-where {
  font-family: -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  font-size: 0.78rem;
  color: var(--muted);
  margin-left: auto;
  text-align: right;
}

.options li.active .option-where { color: var(--rule); }

/* ---- pro mode ---- */

details.pro {
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  margin: 1.8rem 0;
  interpolate-size: allow-keywords;
}

details.pro > summary {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.9rem 0;
  cursor: pointer;
  list-style: none;
}

details.pro > summary::-webkit-details-marker { display: none; }

details.pro > summary::before {
  content: "+";
  font-size: 1.1rem;
  line-height: 1;
  width: 1rem;
  color: var(--muted);
}

details.pro[open] > summary::before { content: "–"; }

/* Animate the panel open/closed. `::details-content` and `interpolate-size`
   let the browser tween height: auto <-> 0 without JS measuring scrollHeight;
   unsupported browsers just fall back to the instant native toggle. */
details.pro::details-content {
  height: 0;
  overflow: hidden;
  opacity: 0;
  transition: height 0.3s ease, opacity 0.3s ease, content-visibility 0.3s allow-discrete;
}

details.pro[open]::details-content {
  height: auto;
  opacity: 1;
}

.pro-title {
  font-family: -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.pro-price { margin-left: auto; }

/* The same fields serve two masters. Inside the disclosure they are a nested
   aside and sit indented under it; on the upgrade screen they are the whole
   page, so the indent belongs to the disclosure, not to the fields. */
.pro-body { padding-bottom: 1.4rem; }

details.pro > .pro-lede,
details.pro > label.switch,
details.pro > .pro-body { padding-left: 1rem; }

.pro-lede { margin-top: 0; max-width: 30rem; }

.pro-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  gap: 0 1rem;
}

.pro-grid .field { margin-bottom: 0.9rem; }

input[type="date"],
input[type="number"],
select {
  width: 100%;
  padding: 0.55rem 0.6rem;
  font-family: inherit;
  font-size: 1rem;
  color: var(--ink);
  background: #fffdf8;
  border: 1px solid var(--rule);
  border-radius: 0;
}

.stay { margin: -0.4rem 0 1rem; }

.radius-row {
  display: grid;
  grid-template-columns: 1fr 5.5rem;
  gap: 0 0.6rem;
}

fieldset.toggles {
  border: 0;
  padding: 0;
  margin: 1.2rem 0 0.6rem;
}

fieldset.toggles legend {
  font-family: -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 0;
  margin-bottom: 0.5rem;
}

label.switch {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  margin-bottom: 0.7rem;
  font-family: inherit;
  font-size: 0.95rem;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink);
  cursor: pointer;
}

label.switch input { margin-top: 0.3rem; flex: none; }

label.switch em {
  display: block;
  font-style: normal;
}

/* ---- diets ---- */

.diet-lede { margin: -0.2rem 0 0.9rem; }

.diet-groups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: 0 1.4rem;
}

.diet-group { margin-bottom: 0.6rem; }

.diet-group-title {
  margin: 0 0 0.45rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-size: 0.68rem;
}

.diet-group label.switch { margin-bottom: 0.5rem; }

/* ---- disambiguation ---- */

fieldset.choice {
  border: 0;
  border-top: 1px solid var(--rule);
  padding: 0;
  margin: 0 0 1.8rem;
}

fieldset.choice legend {
  padding: 0.9rem 0 0.5rem;
  color: var(--muted);
  font-size: 0.95rem;
}

fieldset.choice legend strong { color: var(--ink); }
fieldset.choice legend .muted { display: block; margin-top: 0.2rem; }

label.choice-row {
  display: flex;
  align-items: baseline;
  gap: 0.7rem;
  padding: 0.55rem 0.4rem;
  border-bottom: 1px solid var(--rule);
  font-family: inherit;
  font-size: 1rem;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink);
  cursor: pointer;
}

label.choice-row:hover { background: rgba(0, 0, 0, 0.04); }

label.choice-row > span {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  flex: 1;
}

@media (max-width: 480px) {
  .option-where { font-size: 0.72rem; }
  .pro-body { padding-left: 0; }
}
