/* ============================================================================
   Airframe

   Three themes live at the top. Change `theme` in config.ini to switch, or
   edit the colours here if you want your own. Everything below the themes
   uses the variable names, so nothing else needs touching.
   ========================================================================= */

:root,
[data-theme="daylight"] {
  /* A neutral off-white ground with white panels on top, so cards and the
     ledger sit *on* something instead of dissolving into the page.
     Neutral rather than blue-grey on purpose: a tinted background shifts how
     every photograph on it reads, which on a photography site matters. */
  --bg:        #f6f6f7;
  --sunk:      #eeeef0;
  --panel:     #ffffff;
  --raised:    #e9e9ed;
  --line:      #e2e2e7;
  --line-firm: #cbcbd3;
  --text:      #14161a;
  --quiet:     #63676e;
  --accent:    #0a63d8;
  --accent-in: #ffffff;
  --good:      #0d7d4d;
  --warn:      #a2620a;
  --bad:       #c02626;
  --tint:      rgba(10, 99, 216, 0.07);
  --shadow:    0 1px 2px rgba(16, 21, 27, 0.06), 0 8px 24px rgba(16, 21, 27, 0.06);
  --photo-bg:  #eceff3;
}

[data-theme="midnight"] {
  --bg:        #0a0c0f;
  --sunk:      #0f1216;
  --panel:     #141920;
  --raised:    #1d242d;
  --line:      #262e39;
  --line-firm: #3a4552;
  --text:      #e9edf2;
  --quiet:     #8b98a8;
  --accent:    #55a8ff;
  --accent-in: #06131f;
  --good:      #3ddc97;
  --warn:      #ffb64d;
  --bad:       #ff6b6b;
  --tint:      rgba(85, 168, 255, 0.12);
  --shadow:    0 1px 2px rgba(0, 0, 0, 0.4), 0 10px 30px rgba(0, 0, 0, 0.35);
  --photo-bg:  #000000;
}

[data-theme="blueprint"] {
  --bg:        #0b1a2b;
  --sunk:      #0e2036;
  --panel:     #122943;
  --raised:    #17334f;
  --line:      #1f4265;
  --line-firm: #2d5a83;
  --text:      #dcebf9;
  --quiet:     #7fa3c4;
  --accent:    #4fd1ff;
  --accent-in: #052135;
  --good:      #56e0a0;
  --warn:      #ffc971;
  --bad:       #ff8080;
  --tint:      rgba(79, 209, 255, 0.12);
  --shadow:    0 1px 2px rgba(0, 0, 0, 0.35), 0 10px 30px rgba(3, 15, 26, 0.5);
  --photo-bg:  #06121f;
}

/* Faint drafting grid, blueprint only. */
[data-theme="blueprint"] body {
  background-image:
    linear-gradient(rgba(79, 209, 255, 0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(79, 209, 255, 0.045) 1px, transparent 1px);
  background-size: 28px 28px;
}

/* ------------------------------------------------------------------ basics */

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.55 ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI",
        Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

h1 { font-size: 1.8rem; margin: 0 0 6px; letter-spacing: -0.025em; font-weight: 680; }
h2 { font-size: 1.12rem; margin: 0 0 12px; font-weight: 650; letter-spacing: -0.015em; }
h3 { font-size: 0.9rem; margin: 0 0 8px; font-weight: 620; }
p  { margin: 0 0 10px; }

.quiet { color: var(--quiet); }
.tiny  { font-size: 0.8rem; }

/* Registrations and type codes are technical identifiers, so they get a
   technical face. It also makes them scannable in a long list. */
code, .mono {
  font: 0.85em/1.3 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: 0.03em;
}
code {
  background: var(--raised);
  padding: 2px 6px;
  border-radius: 4px;
}
kbd {
  font: 0.75em/1 ui-monospace, SFMono-Regular, Menlo, monospace;
  background: var(--raised);
  border: 1px solid var(--line-firm);
  border-bottom-width: 2px;
  border-radius: 4px;
  padding: 2px 5px;
  color: var(--text);
}

/* --------------------------------------------------------------- top bar */

.bar {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 0 24px;
  height: 58px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 30;
}

.brand {
  display: flex;
  align-items: center;
  gap: 9px;
  font-weight: 660;
  font-size: 1.05rem;
  color: var(--text);
  letter-spacing: -0.03em;
}
.brand:hover { text-decoration: none; }
.brand svg { display: block; color: var(--accent); }

.find { flex: 1; max-width: 400px; position: relative; }
/* `.bar .find input`, not `.find input`: the generic input rule further down
   this file matches with the same weight and, coming later, was winning. The
   left padding was falling back to 11px and the magnifying glass was sitting
   on top of the first letter of the placeholder. */
.bar .find input {
  width: 100%;
  height: 36px;
  padding: 0 14px 0 34px;
  border-radius: 18px;
  border: 1px solid var(--line);
  background: var(--sunk);
  color: var(--text);
  font: inherit;
  font-size: 0.9rem;
}
.find svg {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--quiet);
  pointer-events: none;
}

.bar nav { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.bar nav a {
  padding: 7px 11px;
  border-radius: 7px;
  color: var(--quiet);
  font-size: 0.9rem;
  font-weight: 500;
}
.bar nav a:hover { color: var(--text); background: var(--raised); text-decoration: none; }
.bar nav a.here { color: var(--text); background: var(--raised); }

.badge {
  display: inline-block;
  margin-left: 6px;
  padding: 0 6px;
  border-radius: 9px;
  background: var(--accent);
  color: var(--accent-in);
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 17px;
}

/* ------------------------------------------------------- buttons & fields */

button, .button {
  display: inline-block;
  padding: 9px 16px;
  border-radius: 8px;
  border: 1px solid transparent;
  background: var(--accent);
  color: var(--accent-in);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
}
button:hover, .button:hover { filter: brightness(1.08); text-decoration: none; }
button.plain, .button.plain {
  background: var(--panel);
  color: var(--text);
  border-color: var(--line-firm);
}
button.plain:hover, .button.plain:hover { background: var(--raised); filter: none; }
button.small { padding: 6px 11px; font-size: 0.84rem; }

label { display: block; margin-bottom: 13px; }
.field-name {
  display: block;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--quiet);
  margin-bottom: 5px;
}

input[type="text"], input[type="search"], input[type="date"],
input[type="number"], textarea, select {
  display: block;
  width: 100%;
  padding: 9px 11px;
  border-radius: 8px;
  border: 1px solid var(--line-firm);
  background: var(--panel);
  color: var(--text);
  font: inherit;
  font-size: 0.92rem;
}
textarea { resize: vertical; line-height: 1.5; }
select:disabled {
  background: var(--sunk);
  color: var(--quiet);
  cursor: not-allowed;
}
input:focus, textarea:focus, select:focus {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
  border-color: var(--accent);
}

/* Fields the auto-fill completed, marked so you can see what you didn't type. */
.filled {
  background: var(--tint) !important;
  border-color: var(--accent) !important;
}

.pair  { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
.trio  { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 14px; }

/* Radio pills, for Civilian / Military */
.pills { display: flex; gap: 8px; margin-bottom: 14px; }
.pills label {
  margin: 0;
  padding: 8px 16px;
  border: 1px solid var(--line-firm);
  border-radius: 20px;
  cursor: pointer;
  font-size: 0.9rem;
  display: flex;
  align-items: center;
  gap: 7px;
}
.pills input { accent-color: var(--accent); margin: 0; }
.pills label:has(input:checked) {
  border-color: var(--accent);
  background: var(--tint);
  color: var(--text);
  font-weight: 600;
}

/* Tick boxes, for categories */
.ticks { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 6px; }
.ticks label {
  margin: 0;
  padding: 7px 13px;
  border: 1px solid var(--line-firm);
  border-radius: 7px;
  cursor: pointer;
  font-size: 0.86rem;
  display: flex;
  align-items: center;
  gap: 7px;
  background: var(--panel);
}
.ticks input { accent-color: var(--accent); margin: 0; }
.ticks label:has(input:checked) {
  border-color: var(--accent);
  background: var(--tint);
  font-weight: 600;
}

/* ----------------------------------------------------------------- layout */

main { padding: 26px 24px 70px; max-width: 1560px; margin: 0 auto; }
.narrow { max-width: 720px; margin: 0 auto; }
.head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 20px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

.notices { padding: 14px 24px 0; max-width: 1560px; margin: 0 auto; }
.notice {
  margin: 0 0 8px;
  padding: 11px 15px;
  border-radius: 8px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--quiet);
  background: var(--panel);
  font-size: 0.9rem;
}
.notice.good { border-left-color: var(--good); }
.notice.warn { border-left-color: var(--warn); }
.notice.bad  { border-left-color: var(--bad); }

footer {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 4px 20px;
  padding: 26px 24px 32px;
  margin-top: 40px;
  border-top: 1px solid var(--line);
  color: var(--quiet);
  font-size: 0.84rem;
}
footer a { color: var(--quiet); }
footer a:hover { color: var(--text); }

.empty { text-align: center; padding: 90px 20px; color: var(--quiet); }
.empty h2 { color: var(--text); font-size: 1.3rem; }
.empty .button { margin-top: 8px; }

/* Panels used across the logbook and forms */
.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 18px;
}
.panel + .panel { margin-top: 16px; }

/* ------------------------------------------------------------ photo grids */

/* Justified: rows of photos at their true shape, like a contact sheet.
   Each photo is given a width proportional to how wide it actually is, then
   the row stretches to fill. Nothing gets forced into a square. */
.grid.justified {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.grid.justified .card {
  flex-grow: 1;
  /* Rows grow with the window. 230px everywhere meant a wall of stamps on a
     large screen, on a site whose whole point is the photographs. */
  height: 240px;
  position: relative;
  overflow: hidden;
  border-radius: 10px;
  background: var(--photo-bg);
}
.grid.justified .card img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Stops a lonely last row from stretching one photo across the page. */
.grid.justified::after { content: ''; flex-grow: 999999; }

@media (min-width: 1100px) { .grid.justified .card { height: 290px; } }
@media (min-width: 1500px) { .grid.justified .card { height: 340px; } }

/* Uniform: equal tiles. Tidier, at the cost of cropping every photo. */
.grid.uniform {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 14px;
}
.grid.uniform .card {
  position: relative;
  border-radius: 10px;
  overflow: hidden;
  background: var(--photo-bg);
  aspect-ratio: 3 / 2;
}
.grid.uniform .card img { width: 100%; height: 100%; object-fit: cover; display: block; }

.card { display: block; color: #fff; transition: transform 0.14s ease; }
.card:hover { text-decoration: none; transform: translateY(-2px); }

/* Caption floats over the photo so the picture stays the whole tile.

   It used to appear only on hover, which meant it was invisible on every phone
   and tablet, where there is no such thing as hovering. Now the registration is
   always legible and the rest deepens when you point at it. */
.card-text {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 30px 13px 11px;
  background: linear-gradient(to top, rgba(0,0,0,0.72), rgba(0,0,0,0.28) 45%, rgba(0,0,0,0));
  transition: background 0.16s ease;
  text-shadow: 0 1px 3px rgba(0,0,0,0.45);
}
.card:hover .card-text {
  background: linear-gradient(to top, rgba(0,0,0,0.85), rgba(0,0,0,0.4) 55%, rgba(0,0,0,0));
}
.card-text strong { display: block; font-size: 0.9rem; font-weight: 650; letter-spacing: 0.01em; }
.card-text span {
  display: block;
  font-size: 0.78rem;
  opacity: 0;
  margin-top: 1px;
  transition: opacity 0.16s ease;
}
.card:hover .card-text span { opacity: 0.92; }

.tag-float {
  position: absolute;
  top: 9px;
  padding: 2px 8px;
  border-radius: 20px;
  font-size: 0.71rem;
  font-weight: 600;
  background: rgba(0,0,0,0.6);
  color: #fff;
  backdrop-filter: blur(6px);
}
.tag-float.star { right: 9px; color: #ffce4d; }
.tag-float.flag { left: 9px; }
/* Sits below the star, so a photo that is both saved and liked shows both. */
.tag-float.hearts { right: 9px; top: 34px; color: #ff8095; }
/* Labels for the top-left corner stack there, so a photo that is both first
   and private, or unedited and waiting, shows every label instead of one
   sitting on top of another. */
.tag-stack {
  position: absolute;
  top: 9px;
  left: 9px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}
.tag-stack .tag-float { position: static; }

.pager { display: flex; justify-content: center; align-items: center; gap: 22px; margin-top: 32px; }
/* display:flex would otherwise beat the hidden attribute the scroll script sets. */
.pager[hidden] { display: none; }

.endless-foot { display: flex; justify-content: center; padding: 30px 0 10px; min-height: 20px; }

.filter-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; margin: 12px 0 0; }
.filter-chips .chip { font-size: 0.76rem; }
.filter-chips b { font-weight: 640; }

/* ------------------------------------------------------------ single photo */

.viewer { display: grid; grid-template-columns: minmax(0, 1fr) 370px; gap: 28px; align-items: start; }
.viewer figure { margin: 0; }
/* Not `.viewer img`: that also caught the photographer's little round profile
   picture in the byline and stretched it across the whole column. */
.viewer figure img {
  display: block;
  /* The width and height attributes are on the tag so the browser knows the
     shape before the file lands. These two lines stop those numbers becoming
     the actual size. */
  width: auto;
  height: auto;
  max-width: 100%;
  /* The whole photograph, without scrolling. A tall portrait shot used to run
     off the bottom of the screen and you had to scroll to see the aeroplane. */
  max-height: calc(100vh - 150px);
  margin: 0 auto;
  border-radius: 12px;
  background: var(--photo-bg);
  box-shadow: var(--shadow);
}
.viewer figcaption {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 12px;
  font-size: 0.85rem;
}
.viewer aside { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 20px; }

.titleline { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.titleline h1 { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 1.4rem; }
.titleline form { margin: 0; }
.star-button { background: none; border: none; color: var(--line-firm); font-size: 1.5rem; padding: 0; line-height: 1; }
.star-button.on { color: #f2b53a; }
.star-button:disabled { opacity: 0.4; cursor: default; }

/* ------------------------------------------------------- likes and follows */

.engage { display: flex; align-items: center; gap: 12px; }

.like-button {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: none;
  border: 1px solid var(--line-firm);
  border-radius: 20px;
  color: var(--quiet);
  padding: 3px 11px 3px 9px;
  line-height: 1;
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}
.like-button .heart { font-size: 1.05rem; line-height: 1; }
.like-button:hover:not(:disabled) { border-color: #ff5e79; color: #ff5e79; }
.like-button.on { border-color: #ff5e79; color: #ff5e79; background: rgba(255, 94, 121, 0.09); }
.like-button:disabled { opacity: 0.55; cursor: default; }

.follow-button {
  background: var(--accent);
  color: var(--accent-in);
  border: 1px solid transparent;
  border-radius: 20px;
  padding: 4px 14px;
  font-size: 0.82rem;
  font-weight: 600;
}
.follow-button.big { padding: 7px 20px; font-size: 0.9rem; }
/* Already following reads as a state, not an invitation, so it goes quiet -
   and turns into an obvious "stop" only when the pointer is on it. */
.follow-button.on { background: none; color: var(--quiet); border-color: var(--line-firm); }
.follow-button.on:hover { color: var(--bad); border-color: var(--bad); }
.follow-button.on:hover::after { content: " ✕"; }

.byline {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 9px;
  margin: 14px 0 0;
  padding-top: 13px;
  border-top: 1px solid var(--line);
}
.byline form { margin: 0 0 0 auto; }
.likers { margin: 9px 0 0; line-height: 1.5; }

.people-list, .people-suggest { list-style: none; padding: 0; margin: 18px 0 0; }
.people-list li, .people-suggest li {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 2px;
  border-bottom: 1px solid var(--line);
}
.people-list li p { margin: 3px 0 0; }
.people-list form, .people-suggest form { margin: 0 0 0 auto; }
.people-suggest { max-width: 420px; margin-inline: auto; text-align: left; }

/* --------------------------------------------------------- notifications */

.bell { position: relative; }

.notif-list { list-style: none; padding: 0; margin: 20px 0 0; }
.notif {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 13px 14px;
  border-bottom: 1px solid var(--line);
  border-radius: 8px;
}
/* Unread ones are tinted rather than badged - the whole page is being marked
   read as it's opened, so this is the only chance to show which were new. */
.notif.fresh { background: var(--tint); }
.notif-mark {
  flex: none;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--raised);
  border: 1px solid var(--line);
  font-size: 0.95rem;
}
.notif-words { flex: 1; font-size: 0.92rem; line-height: 1.5; }
.notif-words .tiny { display: block; margin-top: 2px; }
.notif-thumb { flex: none; }
.notif-thumb img {
  width: 62px;
  height: 44px;
  object-fit: cover;
  border-radius: 6px;
  background: var(--photo-bg);
  display: block;
}

.subtitle { color: var(--quiet); font-size: 0.94rem; margin-top: -2px; }

.facts { display: grid; grid-template-columns: auto 1fr; gap: 7px 16px; margin: 18px 0; font-size: 0.9rem; }
.facts dt { color: var(--quiet); }
.facts dd { margin: 0; }

.chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 14px 0; }
.chip {
  padding: 3px 10px;
  border-radius: 20px;
  background: var(--raised);
  border: 1px solid var(--line);
  font-size: 0.79rem;
  color: var(--text);
}
.chip:hover { border-color: var(--accent); text-decoration: none; }

.caption { border-top: 1px solid var(--line); padding-top: 14px; }

.camera { border-top: 1px solid var(--line); margin-top: 16px; padding-top: 14px; font-size: 0.87rem; }
.camera p { margin: 2px 0; }
.settings { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 9px !important; }
.settings span {
  background: var(--raised);
  border-radius: 5px;
  padding: 2px 8px;
  font-size: 0.79rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.editor { margin-top: 18px; border-top: 1px solid var(--line); padding-top: 14px; }
.editor summary { cursor: pointer; color: var(--quiet); margin-bottom: 14px; font-size: 0.9rem; }
.danger { margin-top: 16px; }
.danger button { background: none; border: 1px solid var(--line-firm); color: var(--bad); font-weight: 500; }

.note {
  margin: 14px 0;
  padding: 11px 14px;
  border-left: 3px solid var(--accent);
  background: var(--raised);
  border-radius: 0 8px 8px 0;
  font-size: 0.89rem;
}
.note .quiet {
  display: block;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  margin-bottom: 3px;
}

/* ------------------------------------------------------------ review queue */

.review { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 28px; align-items: start; }
.review figure { margin: 0; }
.review img {
  width: 100%;
  max-height: 76vh;
  object-fit: contain;
  border-radius: 12px;
  background: var(--photo-bg);
}
.review aside { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 20px; }
.review h1 { margin: 8px 0 14px; }
/* The review panel is narrow, and "Registration or military serial" beside its
   answer would leave the answer a sliver. Each label sits above its value. */
.review .review-facts { grid-template-columns: 1fr; gap: 0; }
.review .review-facts dt { margin-top: 9px; font-size: 0.76rem; }
.review .review-facts dt:first-child { margin-top: 0; }
.review .review-facts dd { overflow-wrap: anywhere; }
.note-box { margin: 16px 0; }

button.approve { width: 100%; padding: 13px; font-size: 1rem; background: var(--good); color: #fff; }
.reject-heading { margin: 20px 0 8px; font-size: 0.82rem; }
.reasons { display: flex; flex-direction: column; gap: 7px; }
button.reject {
  text-align: left;
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--line-firm);
  font-weight: 500;
}
button.reject:hover { border-color: var(--bad); color: var(--bad); filter: none; }
button.reject kbd { margin-right: 7px; }
button.reject.block { margin-top: 10px; border-style: dashed; color: var(--bad); }
button.reject.block:hover { border-style: solid; }
.tip { margin-top: 18px; font-size: 0.8rem; line-height: 1.8; }

/* ------------------------------------------------------------ the composer

   The upload page. Two columns: the photos you're adding stay in view on the
   left while you describe them on the right. Deliberately a handful of large
   smart fields rather than a long stack of dropdowns. */

.composer {
  display: grid;
  grid-template-columns: 340px minmax(0, 1fr);
  gap: 34px;
  align-items: start;
  max-width: 1120px;
  margin: 0 auto;
}
.composer-photos { position: sticky; top: 78px; }
.composer-details { padding-bottom: 40px; }

.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  text-align: center;
  padding: 30px 20px;
  border: 2px dashed var(--line-firm);
  border-radius: 14px;
  background: var(--sunk);
  cursor: pointer;
  color: var(--quiet);
  transition: border-color 0.12s ease, background 0.12s ease;
}
.dropzone:hover, .dropzone.over { border-color: var(--accent); background: var(--tint); }
.dropzone strong { color: var(--text); font-size: 0.98rem; margin-top: 6px; }
.dropzone small { color: var(--quiet); font-size: 0.82rem; }

.thumbs { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 12px; }
.thumbs img {
  width: 52px;
  height: 38px;
  object-fit: cover;
  border-radius: 5px;
  background: var(--photo-bg);
}
.thumbs .more {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 38px;
  border-radius: 5px;
  background: var(--raised);
  color: var(--quiet);
  font-size: 0.78rem;
}

.summary {
  margin-top: 16px;
  padding: 13px 15px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  font-size: 0.88rem;
  line-height: 1.9;
}
.summary .dot { margin: 0 7px; color: var(--line-firm); }

/* One dense list of boxes, the way a spotting site asks: label, box, next.
   What gets filled in every time is together at the top; what is empty on
   almost every photo sits behind "More details" further down. */
.form-rows { display: grid; gap: 15px; }
.field-row { display: grid; gap: 3px; min-width: 0; }
.field-row.two-up {
  grid-template-columns: 1fr 1fr;
  gap: 0 14px;
  align-items: start;
}
.field-row.two-up > * { min-width: 0; }
.field-row.wants-filling {
  border-left: 2px solid var(--bad);
  padding-left: 12px;
  margin-left: -14px;
}
.field-row.wants-filling .required { background: var(--bad); color: #fff; }
.field-row.stepped-back { opacity: 0.55; }
.field-row.stepped-back .required { display: none; }
.row-hint { margin: -4px 0 2px; }
.field-row .suggestions { margin-top: 6px; }

.more-details { margin-top: 4px; border-top: 1px solid var(--line); padding-top: 12px; }
.more-details > summary {
  cursor: pointer;
  color: var(--quiet);
  font-size: 0.9rem;
  margin-bottom: 12px;
}
.more-details[open] > summary { margin-bottom: 14px; }
.more-details .field-row { margin-bottom: 14px; }

/* Numbered steps, quietly - guidance without shouting. */
.step { display: grid; grid-template-columns: 30px minmax(0, 1fr); gap: 16px; margin-bottom: 34px; }
.step-no {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--raised);
  color: var(--quiet);
  font-size: 0.8rem;
  font-weight: 700;
  margin-top: 2px;
}
.step-body h2 { font-size: 1.12rem; margin-bottom: 4px; letter-spacing: -0.02em; }
.hint { color: var(--quiet); font-size: 0.88rem; margin-bottom: 14px; }
.optional { font-weight: 400; color: var(--quiet); text-transform: none; letter-spacing: 0; }

.two-up { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
input.big { font-size: 1.15rem; padding: 11px 13px; letter-spacing: 0.05em; }

/* ---- one search field instead of a chain of dropdowns ---- */

.combo-wrap { position: relative; }
.combo { position: relative; }
.combo-list {
  position: absolute;
  z-index: 40;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  margin: 0;
  padding: 4px;
  list-style: none;
  background: var(--panel);
  border: 1px solid var(--line-firm);
  border-radius: 10px;
  box-shadow: var(--shadow);
  max-height: 320px;
  overflow-y: auto;
}
.combo-list li {
  padding: 8px 10px;
  border-radius: 7px;
  cursor: pointer;
  font-size: 0.89rem;
}
.combo-list li:hover, .combo-list li.on { background: var(--tint); }
.combo-list .code {
  display: inline-block;
  min-width: 46px;
  font-weight: 600;
  color: var(--accent);
}

.picked {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: -4px 0 14px;
  padding: 9px 13px;
  background: var(--tint);
  border: 1px solid var(--accent);
  border-radius: 9px;
  font-size: 0.9rem;
}
.picked .code { font-weight: 600; color: var(--accent); }
.picked .from { color: var(--quiet); font-size: 0.8rem; font-style: italic; }
/* A button that is a choice rather than the choice: taking something out,
   clearing a pick, withdrawing. It was only ever styled inside .picked, so
   everywhere else "clear" quietly meant "big blue button", which made the
   gentle option shout as loudly as the real one. */
button.clear, .clear {
  background: none;
  border: none;
  color: var(--quiet);
  font-size: 0.85rem;
  text-decoration: underline;
  padding: 0;
  font-weight: 400;
  cursor: pointer;
}
button.clear:hover, .clear:hover {
  color: var(--ink);
  filter: none;
  background: none;
}

.picked .clear {
  margin-left: auto;
  font-size: 0.8rem;
}

.lookup-note { font-size: 0.84rem; color: var(--quiet); margin: -6px 0 14px; min-height: 1.2em; }
.lookup-note.good { color: var(--good); }
.lookup-note.bad { color: var(--bad); }
.lookup-note.working { font-style: italic; }

/* ---- Civilian / Military ---- */

.segmented { display: inline-flex; border: 1px solid var(--line-firm); border-radius: 9px; overflow: hidden; margin-top: 4px; }
.segmented label { margin: 0; cursor: pointer; }
.segmented input { position: absolute; opacity: 0; pointer-events: none; }
.segmented span {
  display: block;
  padding: 8px 20px;
  font-size: 0.88rem;
  color: var(--quiet);
  border-right: 1px solid var(--line-firm);
}
.segmented label:last-child span { border-right: none; }
.segmented label:has(input:checked) span { background: var(--accent); color: var(--accent-in); font-weight: 600; }

/* ---- hashtags ---- */

.rule-box {
  padding: 13px 15px;
  border-radius: 9px;
  background: var(--sunk);
  border-left: 3px solid var(--warn);
  font-size: 0.85rem;
  line-height: 1.6;
  margin-bottom: 16px;
}

.tagbox {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  min-height: 46px;
  padding: 7px 10px;
  border: 1px solid var(--line-firm);
  border-radius: 9px;
  background: var(--panel);
  cursor: text;
}
.tagbox:focus-within { outline: 2px solid var(--accent); outline-offset: -1px; border-color: var(--accent); }
.tag-chips { display: contents; }
.tag-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 6px 4px 11px;
  border-radius: 16px;
  background: var(--tint);
  border: 1px solid var(--accent);
  font-size: 0.85rem;
  white-space: nowrap;
}
.tag-chip button {
  background: none;
  border: none;
  color: var(--quiet);
  padding: 0 3px;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}
.tag-chip button:hover { color: var(--bad); filter: none; }
.tag-input {
  flex: 1 1 160px;
  width: auto;
  min-width: 140px;
  border: none;
  background: none;
  padding: 5px 2px;
  margin: 0;
}
.tag-input:focus { outline: none; }

.suggestions { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 4px; }
.suggest {
  background: var(--raised);
  border: 1px solid var(--line);
  color: var(--quiet);
  border-radius: 16px;
  padding: 4px 11px;
  font-size: 0.82rem;
  font-weight: 500;
}
.suggest:hover { border-color: var(--accent); color: var(--accent); background: var(--tint); filter: none; }

/* What the form still wants, beside the photo. Red until it is all there,
   then green, and every missing thing jumps to its own box. */
.still-needed { margin-top: 9px; font-size: 0.86rem; color: var(--bad); }
.still-needed.all-there { color: var(--good); }
.jump-to {
  background: none;
  border: none;
  padding: 0;
  color: inherit;
  font: inherit;
  text-decoration: underline;
  cursor: pointer;
}
.jump-to:hover { filter: none; text-decoration: none; }

.submit-big { width: 100%; padding: 15px; font-size: 1.02rem; border-radius: 10px; }

.section-note { color: var(--quiet); font-size: 0.86rem; margin: 12px 0; }

/* The hidden attribute means hidden, everywhere.

   A rule of our own that sets a display - the chip saying what you chose, the
   "they share the photo equally" tick - beats the attribute on its own, so both
   sat on screen with nothing to say. This settles it once rather than per rule. */
[hidden] { display: none !important; }

/* ---------------------------------------------------------------- logbook */

.tiles { display: flex; flex-wrap: wrap; gap: 12px; margin: 14px 0; }
.tile {
  flex: 1 1 120px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 14px 16px;
}
.tile strong {
  display: block;
  font-size: 1.75rem;
  line-height: 1.1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.tile span { color: var(--quiet); font-size: 0.8rem; }

.filters { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 16px 18px; margin-bottom: 20px; }
.filters .fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(165px, 1fr)); gap: 0 14px; }
.filters .actions { display: flex; gap: 10px; align-items: center; margin-top: 6px; flex-wrap: wrap; }
.filters .actions .quiet { margin-left: auto; }

.toolbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.toolbar .spacer { margin-left: auto; }
.toolbar select { width: auto; }
.viewswitch { display: flex; border: 1px solid var(--line-firm); border-radius: 8px; overflow: hidden; }
.viewswitch a {
  padding: 7px 13px;
  font-size: 0.85rem;
  color: var(--quiet);
  background: var(--panel);
}
.viewswitch a.on { background: var(--accent); color: var(--accent-in); }
.viewswitch a:hover { text-decoration: none; }

.sheet { width: 100%; border-collapse: collapse; font-size: 0.87rem; }
.sheet thead th {
  text-align: left;
  padding: 9px 10px;
  border-bottom: 2px solid var(--line-firm);
  color: var(--quiet);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 640;
  white-space: nowrap;
  position: sticky;
  top: 58px;
  background: var(--bg);
  z-index: 5;
}
.sheet thead th a { color: inherit; }
.sheet tbody tr { border-bottom: 1px solid var(--line); }
.sheet tbody tr:hover { background: var(--sunk); }
.sheet td { padding: 8px 10px; vertical-align: middle; }
.sheet td.shot { width: 84px; padding: 5px 10px 5px 0; }
.sheet td.shot img { display: block; width: 74px; height: 50px; object-fit: cover; border-radius: 5px; background: var(--photo-bg); }
.sheet .mono { font-size: 0.85rem; }
.sheet .wrap-cats { display: flex; gap: 4px; flex-wrap: wrap; }
.sheet .mini {
  font-size: 0.7rem;
  padding: 1px 7px;
  border-radius: 10px;
  background: var(--raised);
  color: var(--quiet);
  white-space: nowrap;
}
.scroller { overflow-x: auto; }

.columns { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 16px; margin-top: 24px; }
.columns table { width: 100%; border-collapse: collapse; font-size: 0.87rem; }
.columns tr { border-bottom: 1px solid var(--line); }
.columns tr:last-child { border-bottom: none; }
.columns td { padding: 5px 0; }
.columns td.count { text-align: right; color: var(--quiet); font-variant-numeric: tabular-nums; }

.bars { display: flex; flex-direction: column; gap: 6px; }
.bars .row { display: grid; grid-template-columns: 56px 1fr 42px; gap: 10px; align-items: center; font-size: 0.85rem; }
.bars .track { height: 8px; background: var(--raised); border-radius: 4px; overflow: hidden; }
.bars .fill { height: 100%; background: var(--accent); border-radius: 4px; }
.bars .count { text-align: right; color: var(--quiet); font-variant-numeric: tabular-nums; }

.prompt {
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: 3px solid var(--warn);
  border-radius: 10px;
  padding: 16px;
  margin: 20px 0;
}
.strip { display: flex; gap: 8px; overflow-x: auto; margin-top: 12px; }
.strip img { height: 74px; border-radius: 6px; }

/* --------------------------------------------------------- review history */

.history { list-style: none; padding: 0; margin: 0; }
.history li { display: flex; gap: 16px; padding: 14px 0; border-bottom: 1px solid var(--line); align-items: flex-start; }
.history img { width: 112px; aspect-ratio: 3 / 2; object-fit: cover; border-radius: 6px; background: var(--photo-bg); }
.history p { margin: 0 0 4px; }
.history .filename { font-size: 0.83rem; }
.pill { display: inline-block; padding: 1px 9px; border-radius: 10px; font-size: 0.74rem; text-transform: capitalize; font-weight: 600; }
.pill.approved { background: rgba(13, 125, 77, 0.15); color: var(--good); }
.pill.rejected { background: rgba(192, 38, 38, 0.15); color: var(--bad); }
.pill.pending  { background: rgba(162, 98, 10, 0.15); color: var(--warn); }
.unblock { margin-left: auto; align-self: center; }

/* ------------------------------------ required fields, and not losing work */

.required {
  display: inline-block;
  margin-left: 5px;
  padding: 0 6px;
  border-radius: 9px;
  background: var(--raised);
  color: var(--quiet);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  vertical-align: 1px;
}
.step.wants-filling .required { background: var(--bad); color: #fff; }
.step.wants-filling .step-no { background: var(--bad); color: #fff; }
.step.wants-filling .step-body { border-left: 2px solid var(--bad); padding-left: 14px; margin-left: -16px; }

/* The photo kept on this side after a form came back incomplete. */
.held {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 11px;
  border: 1px solid var(--good);
  background: rgba(13, 125, 77, 0.08);
  border-radius: 11px;
  margin-bottom: 10px;
}
.held img { width: 92px; aspect-ratio: 3 / 2; object-fit: cover; border-radius: 7px; background: var(--photo-bg); }
.held strong { display: block; font-size: 0.9rem; }
.dropzone.slim { padding: 12px; }
.dropzone.slim strong { margin: 0; font-size: 0.87rem; font-weight: 500; }

/* ----------------------------------------------- looks-like-something-else */

.lookalike {
  padding: 13px 15px;
  margin-bottom: 16px;
  border: 1px solid var(--warn);
  border-left-width: 3px;
  border-radius: 9px;
  background: rgba(162, 98, 10, 0.08);
}
.lookalike p { margin: 4px 0 10px; }
.lookalike-row { display: flex; gap: 8px; flex-wrap: wrap; }
.lookalike-row a { display: block; text-align: center; }
.lookalike-row img {
  display: block;
  width: 88px;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: 6px;
  background: var(--photo-bg);
  margin-bottom: 3px;
}

/* ---------------------------------------------------------------- reports */

.report-actions { display: flex; flex-direction: column; gap: 6px; margin-left: auto; align-self: center; }
button.remove { background: var(--bad); color: #fff; }
.badge.alarm { background: var(--bad); color: #fff; }
.badge.quiet-badge { background: var(--raised); color: var(--quiet); }

/* ------------------------------------------------------------- home page */

.eyebrow {
  display: block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 6px;
}

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: 30px;
  align-items: center;
  margin-bottom: 32px;
  padding-bottom: 30px;
  border-bottom: 1px solid var(--line);
}
.hero-photo img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 14px;
  background: var(--photo-bg);
  box-shadow: var(--shadow);
}
.hero-words h1 { font-size: 2rem; letter-spacing: -0.02em; margin-bottom: 2px; }
.hero-sub { font-size: 1rem; color: var(--text); margin-bottom: 2px; }
.hero-where { color: var(--quiet); }
/* Nothing picked yet. This used to be a full-height centred block, which made
   an empty slot the largest thing on the front page of a photography site. Now
   it's a quiet line that gets out of the way of the photographs. */
.hero.empty-hero {
  grid-template-columns: 1fr;
  padding: 0 0 18px;
  margin-bottom: 22px;
}
.hero.empty-hero > div {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}
.hero.empty-hero h1 { font-size: 1.05rem; margin: 0; font-weight: 620; }
.hero.empty-hero p { margin: 0; font-size: 0.88rem; flex: 1 1 260px; }
.hero.empty-hero .eyebrow { margin: 0; }
.hero.empty-hero .button { margin-left: auto; }

.wantstrip {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 12px 16px;
  margin-bottom: 22px;
  background: var(--sunk);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.wantstrip .eyebrow { margin: 0 6px 0 0; }
.want-chip {
  padding: 3px 11px;
  border-radius: 20px;
  border: 1px dashed var(--line-firm);
  color: var(--text);
  font-size: 0.85rem;
}
.want-chip:hover { border-color: var(--accent); border-style: solid; text-decoration: none; }

.tabs {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--line);
  margin-bottom: 6px;
}
.tabs a {
  padding: 9px 15px;
  color: var(--quiet);
  font-size: 0.91rem;
  font-weight: 500;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.tabs a:hover { color: var(--text); text-decoration: none; }
.tabs a.on { color: var(--accent); border-bottom-color: var(--accent); font-weight: 640; }
.tab-blurb { margin-bottom: 18px; }

/* The row of ways to browse, on the home page. Quieter than the old tabs and
   with nothing underneath it: five controls, a sentence explaining whichever
   one you were on, and a border all stacked up before you reached a
   photograph. */
.rail {
  display: flex;
  align-items: center;
  gap: 22px;
  border-bottom: 1px solid var(--line);
  margin: 34px 0 20px;
}
.rail a {
  padding: 0 1px 10px;
  margin-bottom: -1px;
  color: var(--quiet);
  font-size: 0.92rem;
  border-bottom: 2px solid transparent;
}
.rail a:hover { color: var(--text); text-decoration: none; }
.rail a.on { color: var(--text); font-weight: 600; border-bottom-color: var(--text); }
.rail .aside { margin-left: auto; font-size: 0.86rem; }

/* --------------------------------------------------- photo of the day run */

.potd-run { display: flex; flex-direction: column; gap: 10px; }
.potd-card {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.potd-card.is-today { border-color: var(--accent); background: var(--tint); }
.potd-card img { width: 120px; aspect-ratio: 3 / 2; object-fit: cover; border-radius: 7px; background: var(--photo-bg); }
.potd-words { flex: 1; min-width: 0; }
.potd-words strong { display: block; font-size: 1.05rem; }
.potd-note { margin: 6px 0 0; font-size: 0.89rem; font-style: italic; color: var(--quiet); }
.potd-card form { margin-left: auto; }

/* ------------------------------------------------------------- wishlist */

.wish-add {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr) auto;
  gap: 14px;
  align-items: end;
  margin-bottom: 26px;
}
.wish-add label { margin: 0; }

.wish-columns { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px; }
.wishlist { list-style: none; padding: 0; margin: 0; }
.wishlist li {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
}
.wishlist li form { margin-left: auto; }
.wishlist img { width: 72px; aspect-ratio: 3 / 2; object-fit: cover; border-radius: 5px; background: var(--photo-bg); }
.big-reg { font-size: 1.02rem; font-weight: 600; letter-spacing: 0.05em; }
.wishlist.caught .big-reg { color: var(--quiet); }

/* The "caught" mark, and the "new" mark in the ledger. Deliberately a bit
   rubber-stamp: slightly rotated, outlined, ink-coloured. */
.stamp {
  display: inline-block;
  padding: 1px 7px;
  border: 1.5px solid var(--good);
  border-radius: 3px;
  color: var(--good);
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  transform: rotate(-4deg);
  vertical-align: 2px;
}
.caught-chip { border-color: var(--good); color: var(--good); }
.star-mark { color: #f2b53a; }

/* ------------------------------------------------------- ruled logbook page */

.ledger {
  background: var(--panel);
  border: 1px solid var(--line-firm);
  border-radius: 6px;
  box-shadow: var(--shadow);
  overflow: hidden;
  margin-bottom: 8px;
}
.ledger-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  padding: 16px 20px 12px;
  border-bottom: 2px solid var(--text);
}
.ledger-title {
  display: block;
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.ledger-owner { color: var(--quiet); font-size: 0.86rem; }
.ledger-page { display: flex; align-items: baseline; gap: 6px; color: var(--quiet); font-size: 0.82rem; }
.ledger-page strong { font-size: 1.2rem; color: var(--text); }

.ledger-table { width: 100%; border-collapse: collapse; font-size: 0.86rem; }
.ledger-table th {
  text-align: left;
  padding: 8px 10px;
  border-bottom: 1px solid var(--line-firm);
  border-right: 1px solid var(--line);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--quiet);
  white-space: nowrap;
}
.ledger-table th a { color: inherit; }
.ledger-table td {
  padding: 7px 10px;
  border-bottom: 1px solid var(--line);
  border-right: 1px solid var(--line);
  vertical-align: top;
}
.ledger-table th:last-child, .ledger-table td:last-child { border-right: none; }
/* Alternating tint, like the ruled bands on a paper ledger. */
.ledger-table tbody tr:nth-child(even) { background: var(--sunk); }
.ledger-table tbody tr:hover { background: var(--tint); }
.ledger-table .col-no { width: 42px; color: var(--quiet); font-variant-numeric: tabular-nums; text-align: right; }
.ledger-table .cell-date { white-space: nowrap; color: var(--quiet); }
.ledger-table .cell-reg { font-weight: 600; white-space: nowrap; }
.ledger-table .col-remarks { min-width: 200px; color: var(--quiet); }
.ledger-table tr.is-first .cell-reg a { color: var(--good); }

.ledger-table tfoot td {
  padding: 10px;
  border-top: 2px solid var(--line-firm);
  border-bottom: none;
  font-size: 0.82rem;
  color: var(--quiet);
  background: var(--raised);
}
.ledger-table tfoot tr.grand td { font-weight: 700; color: var(--text); border-top: 1px solid var(--line); }

.ledger-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 20px 16px;
  border-top: 1px solid var(--line);
}
/* A signature line, because every real logbook has one. */
.signature {
  font-family: "Snell Roundhand", "Apple Chancery", cursive;
  font-size: 1.35rem;
  color: var(--quiet);
  border-bottom: 1px solid var(--line-firm);
  padding: 0 24px 2px;
}

/* ----------------------------------------------------------- milestones */

.milestones { margin-bottom: 22px; }
.milestone-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 14px; }
.milestone {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px 14px;
}
.milestone-line { font-size: 0.87rem; margin-bottom: 8px; }
.milestone-line strong { font-size: 1.1rem; }
.milestone .track { display: block; height: 6px; background: var(--raised); border-radius: 3px; overflow: hidden; }
.milestone .fill { display: block; height: 100%; background: var(--accent); border-radius: 3px; }

/* ------------------------------------------------------- settings pickers */

.theme-picker { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.theme-picker.two { grid-template-columns: repeat(2, 1fr); }
.theme-option {
  margin: 0;
  padding: 14px;
  border: 1px solid var(--line-firm);
  border-radius: 11px;
  cursor: pointer;
  background: var(--panel);
}
.theme-option.on, .theme-option:has(input:checked) { border-color: var(--accent); background: var(--tint); }
.theme-option input { position: absolute; opacity: 0; pointer-events: none; }
.theme-option strong { display: block; margin-top: 10px; font-size: 0.92rem; }
.theme-option small { color: var(--quiet); font-size: 0.8rem; line-height: 1.45; display: block; margin-top: 2px; }

.swatch { display: flex; height: 44px; border-radius: 7px; overflow: hidden; border: 1px solid var(--line); }
.swatch i { flex: 1; }
.swatch-daylight i:nth-child(1) { background: #ffffff; }
.swatch-daylight i:nth-child(2) { background: #f0f3f6; }
.swatch-daylight i:nth-child(3) { background: #0a63d8; }
.swatch-midnight i:nth-child(1) { background: #0a0c0f; }
.swatch-midnight i:nth-child(2) { background: #1d242d; }
.swatch-midnight i:nth-child(3) { background: #55a8ff; }
.swatch-blueprint i:nth-child(1) { background: #0b1a2b; }
.swatch-blueprint i:nth-child(2) { background: #17334f; }
.swatch-blueprint i:nth-child(3) { background: #4fd1ff; }

.layout-demo { display: flex; gap: 3px; height: 44px; align-items: stretch; }
.layout-demo i { background: var(--raised); border-radius: 4px; border: 1px solid var(--line); }
.layout-justified i:nth-child(1) { flex: 2; }
.layout-justified i:nth-child(2) { flex: 1.2; }
.layout-justified i:nth-child(3) { flex: 2.6; }
.layout-justified i:nth-child(4) { flex: 1; }
.layout-uniform i { flex: 1; }

/* --------------------------------------------------------- narrow screens */

@media (max-width: 980px) {
  .viewer, .review, .composer { grid-template-columns: 1fr; }
  .composer-photos { position: static; }
  .two-up { grid-template-columns: 1fr; }
  .step { grid-template-columns: 1fr; gap: 6px; }
  .step-no { display: none; }
  .pair, .trio { grid-template-columns: 1fr; }
  .autofill .row { grid-template-columns: 1fr; }
  main { padding: 20px 16px 60px; }
  .sheet thead th { position: static; }
  .hero { grid-template-columns: 1fr; }
  .wish-add, .wish-columns { grid-template-columns: 1fr; }
  .theme-picker, .theme-picker.two { grid-template-columns: 1fr; }
  .potd-card { flex-wrap: wrap; }
}

/* ------------------------------------------------------------- account tier */

.tier-note {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 14px;
  border-radius: 9px;
  background: var(--sunk);
  border: 1px solid var(--line);
  font-size: 0.85rem;
  margin-bottom: 14px;
}
.tier-badge {
  padding: 2px 9px;
  border-radius: 20px;
  background: var(--accent);
  color: var(--accent-in);
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

/* ------------------------------------------------- getting your file back */

.original-line {
  margin: 14px 0;
  padding: 11px 14px;
  background: var(--sunk);
  border: 1px solid var(--line);
  border-radius: 9px;
  font-size: 0.89rem;
}
.original-line span { display: block; margin-top: 2px; }

/* Hashtags you've reached for lately, offered above the generic suggestions. */
.suggest.recent {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--tint);
}
.suggestions + .suggestions { margin-top: 6px; }

/* --------------------------------------------- the logbook's stats, folded up

   These used to be a wall of big number tiles at the very top of the logbook.
   Interesting, but not what you came for - so they're one quiet line now, and
   the ledger itself starts the page. Click the line to open the full set. */

.stat-strip {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  margin-bottom: 16px;
}
.stat-strip > summary {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  cursor: pointer;
  list-style: none;
  font-size: 0.88rem;
}
.stat-strip > summary::-webkit-details-marker { display: none; }
.stat-strip > summary:hover { background: var(--sunk); border-radius: 10px; }
.stat-line { color: var(--quiet); }
.stat-line b {
  color: var(--text);
  font-weight: 660;
  font-variant-numeric: tabular-nums;
}
.stat-line .dot { margin: 0 8px; color: var(--line-firm); }
.more-stats { margin-left: auto; }
.more-stats::after { content: " ▾"; }
.stat-strip[open] .more-stats::after { content: " ▴"; }
.stat-strip[open] > summary { border-bottom: 1px solid var(--line); border-radius: 10px 10px 0 0; }
.stat-strip .tiles,
.stat-strip .milestone-row { padding: 0 16px; }
.stat-strip .milestone-row { padding-bottom: 16px; }

@media (max-width: 760px) {
  .stat-line .dot { margin: 0 4px; }
  .stat-strip > summary { font-size: 0.82rem; flex-wrap: wrap; }
}

/* ------------------------------------------------------------ one search box

   The small box in the top bar and this one are the same field. It just gets
   room to breathe once you're on the search page, with the filters folded
   underneath rather than sitting alongside as a rival. */

.searchpage { margin-bottom: 24px; }

.big-search {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 6px 6px 16px;
  border: 1px solid var(--line-firm);
  border-radius: 12px;
  background: var(--panel);
  box-shadow: var(--shadow);
}
.big-search:focus-within { border-color: var(--accent); outline: 2px solid var(--accent); outline-offset: -1px; }
.big-search svg { color: var(--quiet); flex: none; }
.big-search input {
  flex: 1;
  border: none;
  background: none;
  padding: 12px 0;
  font-size: 1.12rem;
  width: auto;
}
.big-search input:focus { outline: none; }
.big-search button { flex: none; padding: 11px 22px; }

.search-summary { margin: 12px 2px; font-size: 0.9rem; }
.searchpage .filters { margin-bottom: 0; }

/* --------------------------------------------------------- signing in, accounts */

.gate { max-width: 420px; padding-top: 30px; }
.gate h1 { margin-bottom: 10px; }
.gate-form {
  margin-top: 20px;
  padding: 22px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow);
}
.gate-form .submit-big { margin-top: 4px; }

.profile-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 20px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.profile-bio { margin-top: 8px; max-width: 60ch; }
.profile-stats {
  padding: 11px 16px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  margin-bottom: 20px;
  font-size: 0.88rem;
}

.role-badge {
  display: inline-block;
  padding: 1px 9px;
  border-radius: 20px;
  background: var(--accent);
  color: var(--accent-in);
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  vertical-align: 1px;
}
.role-badge.mod { background: var(--raised); color: var(--quiet); }
/* Deliberately unlike the owner badge: the whole point of the test account is
   being able to tell at a glance which of the two you're signed in as. */
.role-badge.test {
  background: var(--warn);
  color: var(--bg);
  margin-left: 5px;
}

.test-send { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; margin-top: 14px; }
.test-send label { flex: 1 1 260px; margin: 0; }

.outbox-list { list-style: none; padding: 0; margin: 18px 0; }
.outbox-list li { padding: 4px 0; }
.outbox-list a.on { font-weight: 640; }
.outbox-body {
  background: var(--sunk);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 16px 18px;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 0.85rem;
  line-height: 1.55;
}

.switcher { margin: 0 0 0 4px; }
.switcher button { white-space: nowrap; }
.role-actions { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.role-actions form { margin: 0; }


/* ------------------------------------------------------ profile pictures */

/* A photo the person already uploaded, shown as a circle. No second upload, no
   second file: it points at a thumbnail that already exists. */
.avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--raised);
  flex: none;
  display: inline-grid;
  place-items: center;
  vertical-align: -11px;
}
/* Nobody has a picture set at first, and an empty circle looks broken, so the
   fallback is their initial rather than a silhouette. */
.avatar.letters {
  border: 1px solid var(--line-firm);
  color: var(--quiet);
  font-weight: 640;
  font-size: 0.85rem;
  letter-spacing: 0;
}
.avatar.small { width: 22px; height: 22px; font-size: 0.66rem; vertical-align: -6px; }
.avatar.big { width: 74px; height: 74px; font-size: 1.7rem; vertical-align: 0; }

.bar nav a.mine { display: inline-flex; align-items: center; gap: 6px; }

.profile-head { display: flex; align-items: flex-start; gap: 16px; }
.profile-head > div:first-of-type { flex: 1; }

.avatar-panel { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.avatar-panel h2 { flex-basis: 100%; margin: 0 0 4px; }
.avatar-panel > div { flex: 1 1 260px; }
.avatar-panel p { margin: 0 0 8px; }

.avatar-pick { margin: 14px 0 0; }
.notif .avatar { margin: 0; }


/* ------------------------------------------------- the bar on any screen

   The bar used to be one row that needed 1153px to hold everything. Anything
   narrower - a phone, a small laptop, a half-width window - pushed the end of
   it off the side of the screen where it couldn't be reached or scrolled to.

   Now the same links are laid out along the bar when there's room, and stacked
   inside a menu when there isn't. CSS decides which; no script is involved, so
   there is nothing here that can fail to load.
   ========================================================================= */

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

.bar .add-photo { margin-left: 8px; flex: none; }
.bar .bell { flex: none; }
.on-narrow, .only-in-menu { display: none; }

/* The menu button and its panel: hidden entirely while the wide bar fits. */
.navmenu { display: none; position: relative; flex: none; }
.navmenu > summary {
  list-style: none;
  cursor: pointer;
  padding: 7px 9px;
  border-radius: 7px;
  color: var(--quiet);
  display: flex;
  align-items: center;
}
.navmenu > summary::-webkit-details-marker { display: none; }
.navmenu > summary:hover { color: var(--text); background: var(--raised); }
.navmenu[open] > summary { color: var(--text); background: var(--raised); }
.navitems {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  min-width: 232px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 2px;
  padding: 8px;
  background: var(--panel);
  border: 1px solid var(--line-firm);
  border-radius: 12px;
  box-shadow: var(--shadow);
  z-index: 40;
}
.navitems a {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-radius: 8px;
  color: var(--text);
}
.navitems .switcher { margin: 6px 0 0; padding-top: 8px; border-top: 1px solid var(--line); }

/* The compact one, out on the bar. It says the name, because the version that
   showed the arrows alone and put the name in hover text could not be found:
   an icon you have to hover to identify is not a control, it is a puzzle.
   The name is capped and trimmed with an ellipsis so a long one can never
   push the end of the bar off the screen. */
.switcher.quick { margin: 0; padding: 0; border: 0; flex: none; }
.switcher.quick button {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 12px;
  border-radius: 999px;
  font-size: 0.86rem;
  line-height: 1;
  color: var(--quiet);
  border: 1px solid var(--line);
  background: var(--panel);
}
.switcher.quick button:hover {
  color: var(--text);
  background: var(--raised);
  border-color: var(--line-firm);
}
.switcher.quick .switch-name {
  max-width: 11ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.navitems .switcher button { width: 100%; }
.navitems .badge { margin-left: auto; }

/* A rule and a quiet line inside a menu, for separating your account from the
   tools for running the site. */
.menu-rule { display: block; height: 1px; background: var(--line); margin: 6px 4px; }
.menu-note {
  padding: 2px 12px 6px;
  color: var(--quiet);
  font-size: 0.74rem;
  font-variant-numeric: tabular-nums;
}
.navitems .signout {
  margin: 6px 0 0;
  padding-top: 8px;
  border-top: 1px solid var(--line);
}
.navitems .signout button { width: 100%; }

/* Your avatar, and everything behind it: your account, and, if you run the
   place, the tools for running it. All of that used to be spread along the bar
   and across the footer of every page, where visitors were looking at it. */
.mymenu { position: relative; flex: none; }
.mymenu > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5px 9px 5px 6px;
  border-radius: 999px;
  color: var(--text);
  font-size: 0.9rem;
  font-weight: 500;
}
.mymenu > summary::-webkit-details-marker { display: none; }
.mymenu > summary:hover { background: var(--raised); }
.mymenu[open] > summary { background: var(--raised); }
.mymenu .my-name {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.84rem;
}
.mymenu .chev { color: var(--quiet); font-size: 0.6rem; }
.mymenu .badge { margin-left: 2px; }

.bar .signin {
  padding: 7px 11px;
  border-radius: 7px;
  color: var(--quiet);
  font-size: 0.9rem;
  font-weight: 500;
  flex: none;
}
.bar .signin:hover { color: var(--text); background: var(--raised); text-decoration: none; }

/* One number now, not two. The bar used to hold Home, About, Search, Logbook,
   Wishlist, Settings and your name, and for a moderator also Review, Reports,
   two counts and the account switcher: 1317px of it, which is why the body used
   to carry a class saying "this bar needs to be wide". Everything about you or
   about running the site now lives under your avatar, so what is left fits.
   Measure again if anything is ever added back: a bar wider than the window
   puts its right-hand end somewhere unreachable. */
@media (max-width: 1100px) {
  /* `.bar .wide-nav`, not `.wide-nav`: the rule it has to beat is `.bar nav`,
     and a single class doesn't outrank a class plus an element name. */
  .bar .wide-nav { display: none; }
  .navmenu { display: block; }
  .only-in-menu { display: inline; }
  /* One menu, not two: your links stack inside the same panel as the rest,
     and the switcher goes back to being a full-width row in there. */
  .mymenu { display: none; }
  .switcher.quick { display: none; }
}

/* Phones. The bar becomes two rows: things you tap on top, search underneath,
   full width, where a thumb can actually hit it. */
@media (max-width: 640px) {
  /* Two rows on a phone: things you tap along the top, the search box full
     width underneath where a thumb can actually hit it. */
  .bar {
    flex-wrap: wrap;
    height: auto;
    padding: 10px 14px;
    gap: 8px 10px;
  }
  .brand { margin-right: auto; }
  .find { order: 5; flex-basis: 100%; max-width: none; }
  /* "Add a photo" becomes a + , because the words cost more room than they
     are worth once three things are competing for one row. */
  .bar .add-photo { padding: 7px 14px; margin-left: 0; }
  .on-wide { display: none; }
  .on-narrow { display: inline; font-size: 1.2rem; line-height: 1; }
  .navmenu .navitems { min-width: min(268px, calc(100vw - 28px)); }
  h1 { font-size: 1.35rem; }
}


/* ------------------------------------------------------------ keyboard use

   Fields already showed where you were. Buttons and links didn't, so tabbing
   through a page left you guessing. :focus-visible only shows the ring for
   keyboard use - clicking a button doesn't leave a halo behind. */

a:focus-visible,
button:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 6px;
}

/* Tapping needs a bigger target than pointing. 44px is the size Apple and
   Google both settled on as the smallest a finger can hit reliably. */
@media (max-width: 640px) {
  .bar nav a, .navmenu > summary, .navmenu .navitems a { min-height: 44px; }
  .navmenu .navitems a { padding-top: 11px; padding-bottom: 11px; }
  .like-button, .star-button { min-height: 40px; }
  .star-button { padding: 0 6px; }
}


/* ---------------------------------------------------- the rule, and about */

.rule-note {
  margin-top: 16px;
  padding: 13px 15px;
  border: 1px solid var(--line-firm);
  border-left: 3px solid var(--accent);
  border-radius: 9px;
  background: var(--sunk);
}
.rule-note strong { display: block; margin-bottom: 5px; font-size: 0.92rem; }
.rule-note p { margin: 0 0 6px; font-size: 0.85rem; line-height: 1.5; }
.rule-note p:last-child { margin-bottom: 0; }

/* The About page reads as writing rather than as an interface, so it gets a
   narrower column - a long line of text is tiring to read across. */
/* `margin: 0 auto` matters. Every other page pairs .prose with .narrow, which
   was quietly supplying the centring; the About page uses .prose on its own and
   so sat hard against the left edge of a wide window. Centring belongs to the
   class that sets the width. */
.prose { max-width: 660px; margin-left: auto; margin-right: auto; }
.prose h2 { margin: 30px 0 10px; font-size: 1.06rem; }
.prose p { line-height: 1.65; margin-bottom: 13px; }
.prose ul { line-height: 1.6; padding-left: 22px; }
.prose li { margin-bottom: 9px; }

.prose .lead { font-size: 1.06rem; color: var(--quiet); }

.the-rule {
  font-size: 1.5rem;
  font-weight: 640;
  letter-spacing: -0.02em;
  padding: 18px 22px;
  margin: 18px 0 22px;
  border-radius: 12px;
  background: var(--tint);
  border: 1px solid var(--line-firm);
}

.ticks-list, .crosses-list { list-style: none; padding-left: 0; }
.ticks-list li, .crosses-list li { position: relative; padding-left: 26px; }
.ticks-list li::before {
  content: "\2713";
  position: absolute; left: 0;
  color: var(--good);
  font-weight: 700;
}
.crosses-list li::before {
  content: "\00D7";
  position: absolute; left: 1px;
  color: var(--bad);
  font-weight: 700;
  font-size: 1.15rem;
  line-height: 1.35;
}


/* ------------------------------------------------------- private photos */

.private-choice {
  margin-top: 16px;
  padding: 13px 15px;
  border: 1px solid var(--line-firm);
  border-radius: 9px;
  background: var(--sunk);
}
.private-choice label {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin: 0;
  cursor: pointer;
}
.private-choice input { margin-top: 3px; accent-color: var(--accent); flex: none; }
.private-choice strong { display: block; margin-bottom: 3px; }
.private-choice .tiny { display: block; line-height: 1.5; }

/* The note under the Add button says where the photo goes. Only one half of it
   is true at a time. */
#where-it-goes .if-private { display: none; }
#where-it-goes.is-private .if-public { display: none; }
#where-it-goes.is-private .if-private { display: inline; }

.notice.private-note {
  border-color: var(--line-firm);
  background: var(--raised);
  color: var(--text);
}

.privacy-switch {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 16px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}

/* A private or unedited row in the ledger, and a private tile in the logbook's
   photo view. */
.private-mark,
.unedited-mark {
  display: inline-block;
  padding: 0 7px;
  border-radius: 20px;
  background: var(--raised);
  border: 1px solid var(--line-firm);
  color: var(--quiet);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  vertical-align: 1px;
}
.tag-float.private { left: 9px; top: 9px; }


/* --------------------------------------------------- what a photo is of */

.subject-pills label { font-size: 0.88rem; }
.subject-note { margin: 10px 0 0; }

/* The aircraft steps don't vanish when the photo isn't of an aircraft: a field
   you can't see is a field you can't correct. They step back instead, so it's
   obvious they're no longer the point. */
.step.stepped-back { opacity: 0.55; }
.step.stepped-back .required { display: none; }


/* ------------------------------------------------- tabs on a small screen

   Seven tabs wrapped onto three rows on a phone, pushing the photographs most
   of a screen down. One row that scrolls sideways is the usual answer, and it
   keeps the first thing you see a photograph. */
@media (max-width: 700px) {
  .tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .tabs::-webkit-scrollbar { display: none; }
  .tabs a { flex: none; white-space: nowrap; }

  .rail {
    gap: 18px;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .rail::-webkit-scrollbar { display: none; }
  .rail a { flex: none; white-space: nowrap; }
  .rail .aside { margin-left: 8px; }

  /* The empty photo-of-the-day line reads better stacked than squeezed. */
  .hero.empty-hero .button { margin-left: 0; }
}

/* ---------------------------------------------------------------- tiers
   Two boxes side by side on a wide screen, stacked on a phone. Deliberately
   plain: a pricing page that shouts tends to read as a page that is trying to
   get something out of you. */
.tiers {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
  margin: 24px 0;
}
/* Three across once there's room. Left to wrap on its own, three boxes come
   out as two and then a lonely one, which reads as a mistake. */
@media (min-width: 720px) {
  .tiers { grid-template-columns: repeat(3, 1fr); }
}
.tier {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 18px 20px;
  background: var(--panel);
}
.tier h2 { margin: 0 0 6px; font-size: 1.1rem; }
.tier .price {
  margin: 0 0 2px;
  font-size: 1.5rem;
  font-weight: 600;
}
/* "a month" sits next to the number, not competing with it. */
.tier .price .per { font-size: .82rem; font-weight: 400; color: var(--quiet); }
.tier .billed { margin: 0; font-size: .82rem; color: var(--quiet); }
/* The saving is the reason to pick yearly, so it gets to be the one loud thing
   on the card. Small enough that three of them don't turn the page into a
   shouting match. */
.tier .saving {
  display: inline-block;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .02em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  white-space: nowrap;
}
/* All three price blocks take the same height, so the feature lists start on
   the same line across the row. Free has no billing lines and would otherwise
   sit a centimetre higher than the other two. */
.tier .pricing { min-height: 8.8rem; }
/* The badge sits on its own line rather than beside the price. Allowed to wrap
   on its own it sits alongside on a wide card and below on a narrow one, which
   changes the card's height with the window and breaks the alignment above. */
.tier .saving-line { margin: 4px 0 6px; }
.tier ul { margin: 14px 0 0; padding-left: 18px; }
.tier li { margin-bottom: 4px; }

/* Buying. Deliberately quiet: two buttons per card, the yearly one solid and
   the monthly one plain, so the cheaper-per-month option is the obvious one
   without anything shouting. */
.tier .buy { width: 100%; margin-top: 10px; text-align: center; }
.tier form { margin: 0; }
.tier .on-this-one {
  margin: 12px 0 0;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--good-soft, rgba(0,0,0,.04));
  font-size: .85rem;
  text-align: center;
}

/* ------------------------------------------------------ more than one aircraft
   A formation is the exception, so these rows only appear when asked for and
   sit slightly indented from the main aircraft above them. */
.also-aircraft {
  display: grid;
  grid-template-columns: 1fr 1fr auto;
  gap: 10px;
  align-items: end;
  margin: 10px 0 0 0;
  padding-left: 12px;
  border-left: 2px solid var(--line);
}
.also-aircraft .clear { margin-bottom: 8px; }
/* The chosen type sits under the row's own boxes, across the full width, the
   same as it does under the main aircraft. */
.also-aircraft .row-picked { grid-column: 1 / -1; margin-top: 0; }
/* Where a row says it filled its own type in, from a tail you have logged
   before. Empty until it has something to say, so it takes no room. */
.also-aircraft .row-note { grid-column: 1 / -1; margin: 0; }
.add-aircraft { margin-top: 12px; }
.tickbox { display: flex; gap: 10px; align-items: flex-start; margin-top: 14px; }
.tickbox input { margin-top: 3px; }
.tickbox .tiny { display: block; margin-top: 2px; }

/* ------------------------------------------------------- closing an account
   Deliberately plain and slightly set apart. The form is folded away behind a
   summary, so the destructive button is never one stray click from a page
   people open to change their email. */
.panel.danger { border-color: var(--bad, #c0392b); }
.panel.danger summary { cursor: pointer; margin-top: 10px; }
.closing { margin-top: 12px; }
.closing label { display: block; margin-bottom: 10px; }
button.danger {
  background: var(--bad, #c0392b);
  border-color: var(--bad, #c0392b);
  color: #fff;
}

/* ------------------------------------------------------------- contact form */
.contact-form label { display: block; margin-bottom: 14px; }
.contact-form textarea,
.contact-form select,
.contact-form input[type=text],
.contact-form input[type=email] { width: 100%; }
/* The trap for bots. Hidden from people in every way that matters, including
   from screen readers, so nobody is asked to fill in a field that must stay
   empty. Not display:none, which some bots skip. */
.leave-empty {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Owner tools on somebody's profile. Set apart and plain, so they never read
   as ordinary buttons on a page anyone might be skimming. */
.owner-tools { margin: 18px 0; }
.owner-tools h2 { margin-top: 0; font-size: 1rem; }
.owner-tools form { margin-bottom: 8px; }
.owner-tools summary { cursor: pointer; margin-top: 10px; }


/* Giving somebody a plan, on their profile. */
.gift-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; margin: 12px 0; }
.gift-form label { margin: 0; }
.gift-form select { min-width: 240px; }
.gift-form .quiet { flex-basis: 100%; }


/* ------------------------------------------- changes people have asked for */

.asked-waiting {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin: 14px 0;
  padding: 12px 14px;
  border: 1px solid var(--line-firm);
  border-radius: 10px;
  background: var(--sunk);
  font-size: 0.9rem;
}
.asked-waiting .quiet { flex-basis: 100%; }

.asked-list { display: flex; flex-direction: column; gap: 16px; }
.asked { display: grid; grid-template-columns: 150px 1fr; gap: 18px; align-items: start; }
.asked-shot img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: 9px;
  background: var(--photo-bg);
  display: block;
}
.asked-body { min-width: 0; }

/* Old and new side by side, because the useful question is always "what is it
   changing from", and hunting for that on another page is how a wrong
   correction gets waved through. */
.asked-diff { border-collapse: collapse; margin: 10px 0 14px; font-size: 0.88rem; width: 100%; }
.asked-diff th, .asked-diff td { text-align: left; padding: 5px 12px 5px 0; vertical-align: top; }
.asked-diff thead th { color: var(--quiet); font-weight: 500; font-size: 0.76rem;
                       text-transform: uppercase; letter-spacing: 0.06em; }
.asked-diff tbody th { color: var(--quiet); font-weight: 500; white-space: nowrap; }
.asked-diff .was { color: var(--quiet); text-decoration: line-through; }
.asked-diff .now { color: var(--text); font-weight: 560; }

.asked-decide { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }
.asked-decide label { margin: 0; flex: 1; min-width: 220px; }
.asked-buttons { display: flex; gap: 8px; }
.warn-text { color: var(--warn); }

@media (max-width: 620px) {
  .asked { grid-template-columns: 1fr; }
  .asked-shot img { max-width: 220px; }
}


/* A line under a box saying what the thing you're typing is used for. Sits with
   the field rather than in a paragraph at the bottom, because that is where
   somebody is looking when they decide whether to type it. */
.consent-note {
  display: block;
  margin-top: 6px;
  color: var(--quiet);
  font-size: 0.78rem;
  line-height: 1.5;
}
.consent-note a { color: var(--accent); }
form > .consent-note { margin: 14px 0 4px; }


/* Somewhere for a keyboard to land first: out of sight until it is focused,
   then a proper button at the top of the page. Tabbing through the whole bar
   to reach the photographs, on every page, is the thing this avoids. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 12px 18px;
  background: var(--accent);
  color: var(--accent-in);
  border-radius: 0 0 10px 0;
  font-weight: 560;
}
.skip-link:focus {
  left: 0;
  text-decoration: none;
  outline: 3px solid var(--text);
  outline-offset: 2px;
}
main:focus { outline: none; }

/* ------------------------------------------------------------------- albums
   A way of looking at photographs, so a tile is mostly the photograph. */
.album-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 14px;
  margin-top: 14px;
}
.album-tile {
  display: block;
  text-decoration: none;
  color: inherit;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  background: var(--card);
}
.album-tile:hover { border-color: var(--accent); }
.album-tile img { display: block; width: 100%; height: 118px; object-fit: cover; }
.album-empty {
  height: 118px;
  display: grid;
  place-items: center;
  color: var(--quiet);
  font-size: 1.6rem;
  background: var(--tint);
}
.album-text { padding: 8px 10px 10px; }
.album-text strong { display: block; font-size: 0.92rem; }
.album-head { margin-bottom: 18px; }

/* One "or" of a self-filling album. */
.rule {
  border-left: 2px solid var(--line);
  padding-left: 12px;
  margin: 12px 0;
}
.rule-main {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr auto;
  gap: 10px;
  align-items: end;
}
.rule-main .clear { margin-bottom: 8px; }
.rule-more { margin-top: 8px; }
.rule-extra {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 10px;
  margin-top: 8px;
}
.album-line {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 0;
  border-bottom: 1px solid var(--line);
}
.album-line .in-album { flex: 1; }
.album-line .quiet { flex: 1; }
.chip-form { display: inline; }

@media (max-width: 620px) {
  .rule-main { grid-template-columns: 1fr; }
}

/* An album rule: airport, when, and the rest folded away. */
.rule-main {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  align-items: end;
}
.rule-main .rule-picked { grid-column: 1 / -1; margin-top: 0; }
.rule-when { display: grid; grid-template-columns: 200px 1fr; gap: 10px; margin-top: 10px; }
.rule-when .when-range { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 620px) {
  .rule-main, .rule-when, .rule-when .when-range { grid-template-columns: 1fr; }
}
.album-line { flex-wrap: wrap; }
.album-line .album-where { flex: 1; min-width: 140px; }
.album-line form { display: inline; }

/* --------------------------------------------------------------- edit queue
   A backlog you work through, so it is a list with the picture big enough to
   recognise and the next action beside it, rather than a gallery. */
.progress-strip { margin: 6px 0 18px; }
.progress-figures { font-size: 0.95rem; margin-bottom: 6px; }
.progress-bar {
  height: 8px;
  border-radius: 4px;
  background: var(--tint);
  overflow: hidden;
}
.progress-bar span { display: block; height: 100%; background: var(--accent); }

.sittings { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 18px; }
.sittings .chip { text-decoration: none; }
.sittings .chip.on { border-color: var(--accent); color: var(--accent); }

.queue-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
  margin-bottom: 6px;
}
.queue-day {
  font-size: 0.95rem;
  margin: 22px 0 6px;
  color: var(--quiet);
  font-weight: 600;
}
.queue-day .quiet { font-weight: 400; margin-left: 8px; }
.queue-row {
  display: grid;
  grid-template-columns: auto 90px 1fr auto;
  gap: 14px;
  align-items: center;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
}
.queue-row.sent { opacity: 0.6; }
.queue-thumb img {
  width: 90px;
  height: 62px;
  object-fit: cover;
  border-radius: 6px;
  display: block;
}
.queue-what .mono { font-weight: 600; }
.queue-what .tiny { display: block; }
.queue-send { display: flex; gap: 8px; align-items: center; }
.queue-send input[type=file] { max-width: 190px; font-size: 0.8rem; }

.done-strip { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.done-strip img {
  width: 74px;
  height: 52px;
  object-fit: cover;
  border-radius: 5px;
  display: block;
}

.unedited-note { margin-top: 6px; font-style: italic; }
.swap-preview { max-width: 220px; border-radius: 6px; display: block; margin: 8px 0; }

/* Two versions of the same photograph, side by side. */
.swap { display: grid; grid-template-columns: 2fr 1fr; gap: 20px; margin-bottom: 34px; }
.swap-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.swap-pair figure { margin: 0; }
.swap-pair img { width: 100%; border-radius: 6px; display: block; }
.swap-side .said { font-style: italic; }
.swap-side input[type=text] { width: 100%; margin: 10px 0 6px; }

@media (max-width: 760px) {
  .queue-row { grid-template-columns: auto 70px 1fr; }
  .queue-do { grid-column: 2 / -1; }
  .queue-thumb img { width: 70px; height: 50px; }
  .swap, .swap-pair { grid-template-columns: 1fr; }
}

/* ------------------------------------------------ what gets a photo accepted
   A reference page people read once and come back to when something is turned
   down, so the plan table and the reasons have to be scannable at a glance.
   Named reason-list rather than reasons, which is already the review queue's
   stack of reject buttons. */
.table-wrap { overflow-x: auto; margin: 10px 0 6px; }
.plain-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.plain-table th, .plain-table td {
  text-align: left;
  padding: 8px 12px 8px 0;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.plain-table th { font-weight: 600; color: var(--quiet); font-size: 0.8rem; }
.reason-list { margin: 12px 0 20px; }
.reason-list dt { font-weight: 600; margin-top: 12px; }
.reason-list dd { margin: 3px 0 0; color: var(--quiet); }

/* Previews on the upload page: several photos at once, and tiles for files a
   browser can't draw. Scoped to .many and new classes so a single photo's
   preview looks exactly as it always has. */
.thumbs.many {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 8px;
}
.thumbs.many img { width: 100%; height: 72px; object-fit: cover; border-radius: 6px; }
.thumb-file {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 3px;
  min-height: 72px;
  padding: 8px;
  border: 1px dashed var(--line-firm);
  border-radius: 6px;
  background: var(--panel);
  font-size: 0.75rem;
  overflow-wrap: anywhere;
}
.thumb-file span { color: var(--quiet); }
/* Each chosen photo carries its own X, so one can be taken off without
   choosing the whole lot again. */
.thumb { position: relative; min-width: 0; }
.thumb > img, .thumb > .thumb-file { display: flex; }
.thumb > img { display: block; }
.thumb-remove {
  position: absolute;
  top: 4px;
  right: 4px;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  min-height: 0;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.62);
  color: #fff;
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
}
.thumb-remove:hover { background: var(--bad); filter: none; }
.thumb-more {
  display: grid;
  place-items: center;
  min-height: 72px;
  border-radius: 6px;
  background: var(--tint);
  color: var(--quiet);
  font-size: 0.85rem;
}

/* Waiting for review: the edit queue's row without its tick box. Given its own
   columns, or the tail number drops into the thumbnail's narrow one. */
.queue-row.waiting-row { grid-template-columns: 90px 1fr auto; }
@media (max-width: 760px) {
  .queue-row.waiting-row { grid-template-columns: 70px 1fr; }
  .queue-row.waiting-row .queue-do { grid-column: 1 / -1; }
}
