/*
 * The HeliosSharp identity, shared by every design in this folder.
 *
 * Not invented here. It is the app's own export caption strip, scaled up:
 * `design_handoff_caption_strip/README.md` fixes the ground, the ink, the four
 * opacity steps, the two typefaces, the middle dot separator and the sun glyph,
 * and this file does nothing but apply them to a page. The reason constrains
 * every future edit: the strip is composited under every picture the app
 * exports, so a visitor who has seen a HeliosSharp photograph in a forum thread
 * has already met this typography. A second style would be a second identity.
 *
 * **Everything here is shared. Nothing here belongs to one design.** Two page
 * designs sit beside each other in `site/one/` and `site/two/` so the owner can
 * compare them, and they are deliberately different pages built out of the same
 * parts: if the two ever look like different products, the difference has leaked
 * into this file and should be moved out of it.
 *
 * Three rules come from the handoff and are what keep either page from drifting
 * into a generic dark landing page.
 *
 * 1. **No rules, boxes, plates, cards, shadows or coloured accents.** The strip
 *    forbids them. Hierarchy is opacity and typeface only. One hairline is
 *    permitted, at the top of a section, because a plate ledger has register
 *    lines; nothing else may draw one.
 * 2. **The only colour on the page comes out of the Sun.** Every hue a visitor
 *    sees is inside a photograph. There is no brand colour and there must never
 *    be one, because anything saturated next to an H-alpha frame competes with
 *    it.
 * 3. **Numbers are mono, words are sans.** That split is what makes the page
 *    read as an observing log rather than as marketing.
 *
 * Dark only, deliberately, and there is no light mode: the pictures are
 * near-black at the edges and the page ground is what they bleed into.
 */
/* --- Fonts, self-hosted ------------------------------------------------------
 *
 * Self-hosted rather than pulled from a font CDN, and that is a design decision
 * as much as a privacy one. The site makes **no third-party requests at all**,
 * which is what lets it ship with no cookie banner and keeps `PRICING.md` §4's
 * promise that the site holds nothing and has nothing worth attacking. Latin
 * subsets only: 75 kB for the three faces.
 *
 * IBM Plex is SIL Open Font License 1.1.
 */
@font-face {
  font-family: 'IBM Plex Sans';
  src: url('../assets/fonts/ibm-plex-sans-var.woff2') format('woff2');
  font-weight: 100 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../assets/fonts/ibm-plex-mono-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../assets/fonts/ibm-plex-mono-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* --- Tokens ----------------------------------------------------------------- */

:root {
  /* The strip's two colours. `#0C0C0E` is chosen to sit a half-step above the
     near-black sky of a solar frame, which is exactly the property the page
     needs for a picture to bleed into it without a border. */
  --ground: #0c0c0e;
  --ink: #f4f3f0;

  /* The strip's four opacity steps, plus three the page needs and the strip
     does not: 70% is the wordmark's, 24% is a dormant control, 13% is the ring
     behind the sun glyph, 8% is the one permitted hairline. */
  --ink-100: rgb(244 243 240 / 1);
  --ink-84: rgb(244 243 240 / 0.84);
  --ink-70: rgb(244 243 240 / 0.7);
  --ink-58: rgb(244 243 240 / 0.58);
  --ink-44: rgb(244 243 240 / 0.44);
  --ink-24: rgb(244 243 240 / 0.24);
  --ink-13: rgb(244 243 240 / 0.13);
  --ink-08: rgb(244 243 240 / 0.08);

  --sans: 'IBM Plex Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, 'Cascadia Mono', 'Consolas', monospace;

  /* A page gutter that stays a thumb's width on a phone and stops growing on a
     wide monitor, because the measure is set by the text column and not by the
     window. */
  --gutter: clamp(1.25rem, 4vw, 4.5rem);
  /* The mono rail: section numbers and field labels. Collapses on narrow. */
  --rail: 8.5rem;
  --measure: 34rem;
}

/* --- Reset, minimal --------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink-84);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.62;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/*
 * `height: auto` is load-bearing, not tidiness. Every picture here carries
 * `width` and `height` attributes so the browser can reserve the right box
 * before the file arrives and the page does not jump; without this rule the
 * attribute height is then honoured literally and a 1400 by 962 frame renders
 * 498 wide and 962 tall.
 */
img {
  display: block;
  max-width: 100%;
  height: auto;
}

a {
  color: inherit;
}

/* --- Type ------------------------------------------------------------------- */

/*
 * The display sizes are set in `vw` with a floor and a ceiling rather than at
 * breakpoints, because the headline sits inside the sky of a photograph and has
 * to keep its relationship to the limb at every width.
 */
.display {
  font-size: clamp(2.35rem, 5.6vw, 5rem);
  line-height: 1.02;
  letter-spacing: -0.022em;
  font-weight: 600;
  color: var(--ink-100);
  margin: 0;
  text-wrap: balance;
}

.headline {
  font-size: clamp(1.6rem, 2.9vw, 2.5rem);
  line-height: 1.12;
  letter-spacing: -0.016em;
  font-weight: 600;
  color: var(--ink-100);
  margin: 0;
  text-wrap: balance;
}

.lede {
  font-size: clamp(1.0625rem, 1.35vw, 1.3125rem);
  line-height: 1.5;
  color: var(--ink-84);
  max-width: var(--measure);
  margin: 0;
  text-wrap: pretty;
}

p {
  max-width: var(--measure);
  margin: 0 0 1.1em;
  text-wrap: pretty;
}

/*
 * The mono label. Every section number, field name and unit on the site is one
 * of these, and they are the site's structural device: a plate ledger is
 * organised by its numbering, not by its borders, so this is what replaces the
 * boxes the caption strip forbids.
 */
.label {
  font-family: var(--mono);
  font-size: 0.6875rem;
  line-height: 1.4;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-44);
  font-weight: 400;
  margin: 0;
}

.label--bright {
  color: var(--ink-70);
}

/* Numbers, always mono, always tabular so a column of them lines up. */
.num {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.015em;
}

/* --- The maker's mark -------------------------------------------------------
 *
 * Two concentric circles, exactly as the caption strip draws them: a solid ink
 * disc with a 13% ring spread around it. There is no logo file on this site and
 * there must not be one; the mark is two circles and a tracked wordmark, which
 * is what the app itself composites onto every export.
 */

.mark {
  display: inline-flex;
  align-items: center;
  gap: 0.62em;
  text-decoration: none;
  color: var(--ink-70);
}

.mark__glyph {
  width: 1.02em;
  height: 1.02em;
  border-radius: 50%;
  background: var(--ink);
  box-shadow: 0 0 0 0.17em var(--ink-13);
  flex: 0 0 auto;
}

.mark__word {
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.23em;
  text-transform: uppercase;
  color: var(--ink-70);
}

.mark:hover .mark__word,
.mark:focus-visible .mark__word {
  color: var(--ink-100);
}

/* --- Page frame -------------------------------------------------------------- */

.masthead {
  position: relative;
  z-index: 3;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 2rem;
  padding: 1.6rem var(--gutter);
}

/*
 * Navigation is mono and quiet. It is not sticky and it has no backdrop blur:
 * a bar that follows the reader down the page would sit on top of the
 * photographs, which are the argument.
 */
.nav {
  display: flex;
  gap: 1.75rem;
  align-items: baseline;
}

.nav a {
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-44);
  text-decoration: none;
  padding-bottom: 0.15em;
  border-bottom: 1px solid transparent;
  transition: color 0.18s ease, border-color 0.18s ease;
}

.nav a:hover,
.nav a:focus-visible {
  color: var(--ink-100);
  border-bottom-color: var(--ink-24);
}

/*
 * Narrow: the mark takes its own line and the links sit under it in one row.
 * Three tracked mono labels cannot share a 375 px line with the wordmark, and
 * letting them wrap in place stacks each label into a column of single words.
 */
@media (max-width: 34rem) {
  .masthead {
    flex-direction: column;
    align-items: flex-start;
    gap: 1rem;
  }

  .nav {
    gap: 1.25rem;
    flex-wrap: wrap;
  }
}

/* --- Plates ------------------------------------------------------------------
 *
 * A plate is a photograph on this page, and the masking is the signature of the
 * whole design.
 *
 * A solar frame's sky is within a hair of the page ground, so a picture placed
 * on this background with its edges feathered has no boundary at all: the limb
 * appears to curve out of the page itself. That is why `--ground` may not be
 * lightened and why there is no light mode. It is also why plates carry no
 * border, no radius and no shadow, over and above the caption strip's ban on
 * them: any of the three would draw the edge the mask exists to remove.
 *
 * `mask-image` and not a gradient overlay, because an overlay would have to be
 * the ground colour and would then be wrong the moment anything sits behind the
 * picture.
 */
.plate {
  position: relative;
  width: 100%;
}

.plate img {
  width: 100%;
  height: auto;
}

.plate--feather img {
  -webkit-mask-image: radial-gradient(120% 120% at 50% 50%, #000 55%, transparent 100%);
  mask-image: radial-gradient(120% 120% at 50% 50%, #000 55%, transparent 100%);
}

/*
 * The caption strip, in the browser.
 *
 * A transcription of the exported band, at page scale rather than export scale,
 * so a reader meets the same object here that they will composite under their
 * own pictures. Reading order is fixed by the handoff and is not a layout
 * preference: who, when, what with, how sharp, how made, whose app.
 *
 * **Absent fields are omitted entirely.** No dashes, no "Unknown", no reserved
 * slots. The sparse case, a timestamp at the left and the mark at the right
 * with air between them, is the design working rather than the design failing.
 */
.caption {
  display: flex;
  align-items: flex-start;
  gap: 2.4em;
  padding: 0.85rem 0 0;
  font-size: 0.8125rem;
}

/*
 * The strip is a three-column band at export width and cannot be one at 500 px.
 * A container query rather than a media query, because what decides this is how
 * wide the picture is, not how wide the window is: the same strip appears under
 * a full-bleed plate and beside a column of copy on the same screen.
 */
.plate-frame {
  container-type: inline-size;
}

@container (max-width: 34rem) {
  .caption {
    flex-direction: column;
    gap: 0.55em;
  }

  .caption__identity,
  .caption__record,
  .caption__mark {
    padding-top: 0;
    min-width: 0;
  }
}

.caption__identity {
  flex: 0 0 auto;
  min-width: 10em;
}

.caption__record {
  flex: 1 1 auto;
  min-width: 0;
  padding-top: 0.14em;
}

.caption__mark {
  flex: 0 0 auto;
  padding-top: 0.3em;
}

.caption__name {
  font-weight: 500;
  color: var(--ink-100);
  letter-spacing: 0.004em;
  line-height: 1.15;
}

.caption__time {
  font-family: var(--mono);
  color: var(--ink-58);
  letter-spacing: 0.02em;
  font-size: 0.9em;
  line-height: 1.2;
}

.caption__gear {
  color: var(--ink-84);
  line-height: 1.3;
}

.caption__scale {
  font-family: var(--mono);
  color: var(--ink-56, var(--ink-58));
  letter-spacing: 0.015em;
  font-size: 0.9em;
  line-height: 1.25;
}

.caption__note {
  color: var(--ink-44);
  line-height: 1.4;
  font-size: 0.94em;
  max-width: 44em;
}

/* --- Sections ---------------------------------------------------------------- */

/*
 * The one permitted hairline, and only at the top of a section. A plate ledger
 * has register lines; nothing else on this site may draw one.
 */
.section {
  padding: clamp(4rem, 9vw, 8.5rem) var(--gutter);
  border-top: 1px solid var(--ink-08);
}

.section--flush {
  border-top: 0;
}

/*
 * The rail layout: a narrow mono column of numbers and labels beside a wide
 * column of everything else. Taken from the app's own sticky section rail, and
 * it is what gives the page its asymmetry without needing a device to draw one.
 */
.rail {
  display: grid;
  grid-template-columns: var(--rail) minmax(0, 1fr);
  gap: 0 clamp(1.5rem, 4vw, 4rem);
  align-items: start;
}

@media (max-width: 46rem) {
  .rail {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.9rem;
  }
}

/*
 * Vertical rhythm inside a rail's content column.
 *
 * `.label`, `.headline` and `.lede` all carry `margin: 0` so they can be
 * composed freely, which means a block that stacks all three has them touching.
 * Every section on both designs stacks all three, so the spacing belongs here
 * rather than being repeated in each page's stylesheet.
 */
.rail > div > * + * {
  margin-top: 0.95rem;
}


/* --- Calls to action ---------------------------------------------------------
 *
 * A link, not a button. There is no filled rectangle anywhere on this site: the
 * caption strip's ban on plates and coloured accents applies here more than
 * anywhere, because a solid pill of colour beside an H-alpha frame is the one
 * thing guaranteed to pull the eye off the photograph.
 *
 * The underline is drawn at 24% and lifts to full on hover, so the control is
 * legibly a control without being loud.
 */
.cta {
  display: inline-flex;
  align-items: baseline;
  gap: 0.55em;
  font-family: var(--sans);
  font-weight: 500;
  font-size: 1.0625rem;
  color: var(--ink-100);
  text-decoration: none;
  padding-bottom: 0.3em;
  border-bottom: 1px solid var(--ink-24);
  transition: border-color 0.18s ease;
}

.cta:hover,
.cta:focus-visible {
  border-bottom-color: var(--ink);
}

.cta__arrow {
  font-family: var(--mono);
  font-size: 0.9em;
  color: var(--ink-58);
}

.cta-note {
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  color: var(--ink-44);
  margin-top: 0.9rem;
}

:focus-visible {
  outline: 1px solid var(--ink-70);
  outline-offset: 3px;
}

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

.footer {
  padding: clamp(3rem, 6vw, 5rem) var(--gutter);
  border-top: 1px solid var(--ink-08);
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem 3rem;
  align-items: baseline;
  justify-content: space-between;
}

.footer p {
  margin: 0;
  color: var(--ink-44);
  font-size: 0.875rem;
}
