/* yh.net.ua — shared styles.

   Pixel minimal on the One Light and One Dark palettes. One typeface
   (JetBrains Mono) at one weight, for both languages; the scale separates the
   levels, not the boldness. The masthead keeps everything on one line in two shapes:
   the nav inline from 48rem, behind a burger below it — see the Menu section. Every box on the page is the same box: 2px of --edge on --paper,
   square corners, no shadow. The theme's purple carries the square markers, its
   orange carries the links, and its cyan is the water under the logo's sun.

   The greys are the one place both themes depart from their source: see the note
   above :root. */

/* Light is the written default; the system preference switches to dark unless the
   reader has explicitly chosen light, and [data-theme] — set by the toggle — wins
   over both. Neither palette uses the theme's own greys for prose: One Light's
   comment grey sits at 2.47:1 on its background and One Dark's at 2.32:1, so the
   greys here are darkened and lifted until every pairing clears AA.

   The links and the logo's sun take their orange from the portrait on /members
   rather than from One Dark, so the accent on the page and the accent in the
   picture are the same colour: #ed8838, which measures 5.45:1 on the dark ground
   and 6.00:1 inside a dark frame. It cannot serve the light theme — 2.46:1 and
   2.25:1 there, no better than the #d19a66 it replaced — so light carries the same
   hue (26.5 degrees) at full saturation, darkened until it clears AA: #a14700, at
   5.89:1 on the page and 5.40:1 inside a frame. */

:root {
  color-scheme: light;

  --ground:  #fafafa;
  --paper:   #f0f0f1;
  --emph:    #1f2127;
  --ink:     #383a42;
  --muted:   #61646d;
  --edge:    #7c7f88;
  --rule:    #8a8c94;
  --accent:  #a14700;
  --marker:  #a626a4;
  --water:   #0184bc;

  --face: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
}


@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --ground:  #282c34;
    --paper:   #21252b;
    --emph:    #e6e6e6;
    --ink:     #abb2bf;
    --muted:   #9da5b4;
    --edge:    #8b93a1;
    --rule:    #787e8a;
    --accent:  #ed8838;
    --marker:  #c678dd;
    --water:   #56b6c2;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --ground:  #282c34;
  --paper:   #21252b;
  --emph:    #e6e6e6;
  --ink:     #abb2bf;
  --muted:   #9da5b4;
  --edge:    #8b93a1;
  --rule:    #787e8a;
  --accent:  #ed8838;
  --marker:  #c678dd;
  --water:   #56b6c2;
}

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

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--face);
  font-size: 1.25rem;
  font-weight: 400;
  line-height: 1.55;
}

.sheet {
  max-width: 48rem;
  margin: 0 auto;
  padding: 1.5rem 1rem 3rem;
}

@media (min-width: 40rem) {
  .sheet { padding: 2.5rem 2rem 5rem; }
}

/* Masthead */

/* The masthead stays put while the page moves under it. The padding it takes on
   is the sheet's own top padding, pulled back by the same amount, so nothing
   shifts: the header sits where it always did, and once stuck it still has that
   much background above it instead of text touching the top of the screen. */
.masthead {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: baseline;
  gap: 0.5rem 1.25rem;
  margin-top: -1.5rem;
  padding-top: 1.5rem;
  padding-bottom: 0.875rem;
  background: var(--ground);
  border-bottom: 2px solid var(--edge);
}

@media (min-width: 40rem) {
  .masthead {
    margin-top: -2.5rem;
    padding-top: 2.5rem;
  }
}

/* Plain inline, not a flex box: a flex container takes its baseline from its first
   item, which here is the mark, and that pushed the domain 8px above the nav links.
   Inline keeps the text's own baseline, so the wordmark sits on the same line as
   everything else in the masthead.

   margin-right: auto is what keeps the mark and the domain on the left edge, level
   with the headline and every other line of the page, in both shapes. It eats the
   free space on the row, so the nav and the controls are pushed to the right; the
   masthead's justify-content: flex-end then only has anything left to do on a row
   the mark is not on. Without the auto margin flex-end packs the mark rightwards
   too, and it drifts with the window — 87px off the content edge at 500px, 187px at
   600px, 97px once the sheet stops widening. Do not add auto margins to the nav or
   the controls as well: several autos on one row split the free space between them
   and the mark leaves the edge again. */
.masthead .wordmark {
  margin-right: auto;
  font-size: 1.25rem;
  color: var(--emph);
  text-decoration: none;
  white-space: nowrap;
}

/* The sunrise mark. Its two colours come from the palette, so it follows the
   theme with everything else; the sun takes the accent, the horizon the water. */
/* On a phone the masthead carries the mark alone. The domain is clipped rather
   than removed, so the link keeps its name for a screen reader — the mark itself
   is aria-hidden and would leave the link nameless. */
.wordmark .name {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* 30rem, not the 40rem used elsewhere: by 480px there is room for the domain
   beside the mark, and holding it back to 640px left a lone sun with a hole
   next to it in a narrow browser window. */
@media (min-width: 30rem) {
  .wordmark .name {
    position: static;
    width: auto;
    height: auto;
    margin: 0;
    overflow: visible;
    clip-path: none;
  }
}

.logo {
  width: 1.65em;
  height: 1.65em;
  /* The horizon sits 10 rows down a 16-row grid, so it lands on the text baseline
     when the box hangs 1.65em x 6/16 below it: the sun rises out of the same line
     the domain is set on. */
  vertical-align: -0.62em;
  --logo-sun: var(--accent);
  --logo-line: var(--water);
}

/* The gap belongs with the text: it appears at the same width the domain does. */
@media (min-width: 30rem) {
  .logo { margin-right: 0.5rem; }
}

.masthead .wordmark:hover { color: var(--accent); }

/* The menu. Two shapes: the three links inline from 48rem up, and behind a burger
   button below it, where the masthead has no room for them — inline they want 256px
   in English and 333px in Ukrainian, and a 320px window leaves 288px for the whole
   row. 48rem is where the wide shape fits and is also where the sheet reaches its
   full width, so nothing about the layout changes above it.

   The open/closed state is a checkbox, not a <details>. A details was the first
   choice — better semantics, no state element in the markup — but the wide shape
   needs the links rendered while the disclosure is closed, and Firefox does not let
   author CSS reveal the contents of a closed details (Chrome does; it was measured
   in both). The alternative, a second copy of the nav for the wide shape, would put
   the labels in two places on all eight pages. So the state lives on a checkbox,
   which is entirely author-controlled, needs no JavaScript, and keeps one copy of
   the links. The trade is that a screen reader announces the button as a checkbox
   rather than as an expandable button.

   A small script at the end of the page closes the menu on Escape and on a click
   outside. Without it the button still opens and closes; it just stays open until
   clicked again. */

/* Focusable but unseen, the same way the wordmark's domain is hidden on a phone.
   display: none would take it off the keyboard with it. */
.menu-state {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Framed like the toggle beside it, and last of the three — the burger sits at the
   far right end of the masthead, after the language switch and the theme toggle.
   order does that rather than the markup, because the checkbox has to precede the
   panel it reveals and the wide shape needs the nav ahead of the controls.

   align-self: center, not the baseline the group aligns on: the two controls beside
   it are text boxes and take their baseline from the text, while this one holds a
   lone SVG, which has none — the browser synthesises one from the box and put the
   button 7.9px higher than its neighbours, which read as a different size rather
   than a different position. All three boxes are 39.9px tall, so centring lines
   them up exactly. */
.menu-button {
  order: 1;
  align-self: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.1875rem 0.625rem 0.3125rem;
  border: 2px solid var(--edge);
  background: var(--paper);
  color: var(--emph);
  font-size: 1.125rem;
  line-height: inherit;
  cursor: pointer;
}

.menu-button:hover {
  background: var(--emph);
  color: var(--ground);
}

/* The ring belongs on the label, since the input it belongs to is the hidden one. */
.menu-state:focus-visible + .menu-button {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

/* Open reads as pressed, the same inversion hover uses. */
.menu-state:checked + .menu-button {
  background: var(--emph);
  color: var(--ground);
}

/* 1.55em is the line height the text controls beside it get, so the button ends up
   exactly as tall as they are; the viewBox keeps its own 12:10 ratio inside that
   box and centres itself. */
.burger {
  width: 0.875em;
  height: 1.55em;
}

/* Closed by default. Its containing block is the masthead — the nearest positioned
   ancestor, by virtue of being sticky — so top: 100% drops it just under the
   masthead's rule and right: 0 lines its right edge up with the control group's.
   Right-aligned rather than left: the button is the rightmost thing in the
   masthead, and a panel opening rightward from there would run off the screen. */
.menu-panel {
  display: none;
  position: absolute;
  top: calc(100% + 0.375rem);
  right: 0;
  z-index: 20;
  flex-direction: column;
  gap: 0.625rem;
  padding: 0.875rem 1.125rem;
  border: 2px solid var(--edge);
  background: var(--paper);
  font-size: 1.125rem;
  white-space: nowrap;
}

.menu-state:checked ~ .menu-panel { display: flex; }

.menu-panel a { text-decoration: none; }

.menu-panel a:hover { text-decoration: underline; }

.menu-panel a[aria-current="page"] {
  color: var(--muted);
  text-decoration: none;
}

/* The wide shape: no button, and the panel stops being a panel — it lays the links
   out in a row, in the flow, with no frame of its own. The extra margin brings the
   distance to the language switch up to the masthead's own 1.25rem, so the links
   read as navigation rather than as part of the control group. */
@media (min-width: 48rem) {
  .menu-state,
  .menu-button { display: none; }

  .menu-panel {
    display: flex;
    position: static;
    flex-direction: row;
    gap: 0.25rem 1.25rem;
    margin-right: 0.625rem;
    padding: 0;
    border: 0;
    background: none;
  }
}

/* Theme toggle. Hidden until the head script proves scripting is on, so a reader
   without it never meets a dead control — the system preference still applies. */

.theme-toggle { display: none; }

/* Framed like the call to action, at masthead scale. */
:root.js .theme-toggle {
  display: inline-flex;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0;
  padding: 0.1875rem 0.625rem 0.3125rem;
  border: 2px solid var(--edge);
  background: var(--paper);
  color: var(--emph);
  font: inherit;
  font-size: 1.125rem;
  line-height: inherit;
  cursor: pointer;
}

.theme-toggle:hover {
  background: var(--emph);
  color: var(--ground);
}

.theme-toggle:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

/* Held at the width of the longest word any language puts here — "світла", six
   characters, against "light" at five — so switching the theme or the language
   changes the word and nothing else. Without it the control grew nine pixels wider
   in one theme than the other, enough for the masthead to jump between one row and
   two on a 414px phone. */
.theme-toggle .label {
  min-width: 6ch;
  text-align: left;
}

.theme-toggle .mark {
  flex: none;
  width: 0.625rem;
  height: 0.625rem;
  background: var(--marker);
}

/* On hover the panel turns to --emph, where the purple square would sit at 2.4:1;
   currentColor keeps the mark legible against it. */
.theme-toggle:hover .mark { background: currentColor; }

/* The controls travel as one flex item, so they make a single wrapping decision
   instead of three competing ones, and the gap between them is tighter than the
   masthead's own 1.25rem — at that distance they read as separate items rather than
   as one group.

   Their order is the markup's: the theme toggle, then the language switch, then the
   menu button, which order: 1 sends to the end. Written in the markup rather than
   with order wherever it can be, so that the reading and tab order match what is
   on screen; order is used only for the button, whose markup position is fixed by
   the checkbox having to precede the panel it reveals. */
.masthead-controls {
  flex: none;
  display: flex;
  align-items: baseline;
  gap: 0.625rem;
}

/* Language switch. A link to the same page in the other language, not a button:
   there is nothing to toggle client-side, so it needs no :root.js gate and works
   with scripting off. The box is the theme toggle's without the marker — it sits
   just after it — so the controls read as one group at the end of the masthead. */

.lang-switch {
  display: inline-flex;
  align-items: baseline;
  padding: 0.1875rem 0.625rem 0.3125rem;
  border: 2px solid var(--edge);
  background: var(--paper);
  color: var(--emph);
  font-size: 1.125rem;
  text-decoration: none;
}

/* Beats the page's own a:hover, which would otherwise leave --emph text on an
   --emph panel. */
.lang-switch:hover {
  background: var(--emph);
  color: var(--ground);
}

/* Jump to the top or the bottom of the page. Like the theme toggle it appears
   only with scripting, and it hides itself on a page short enough not to scroll. */

.scroll-jump { display: none; }

:root.js .scroll-jump {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 20;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 2px solid var(--edge);
  background: var(--paper);
  color: var(--emph);
  cursor: pointer;
}

:root.js .scroll-jump[hidden] { display: none; }

@media (min-width: 40rem) {
  /* Anchored to the sheet, not to the window: the sheet is 48rem wide and centred,
     so its right edge sits 50% - 24rem from the right of the viewport. The button
     is parked beside it with a 0.9375rem (15px) gap — hence the extra 2.75rem, its
     own width — so it never covers the text. Below about 916px there is no room
     out there, and max() falls back to the same 15px measured from the window. */
  :root.js .scroll-jump {
    right: max(0.9375rem, calc(50% - 24rem - 0.9375rem - 2.75rem));
    bottom: 0.9375rem;
  }
}

.scroll-jump:hover {
  background: var(--emph);
  color: var(--ground);
}

.scroll-jump:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

.scroll-jump .arrow {
  width: 1.125rem;
  height: 1.125rem;
}

.scroll-jump[data-dir="up"] .arrow { transform: rotate(180deg); }

/* Headings. One face at one weight, so the scale does the work. */

.hero { margin: 2.75rem 0 0; }

.page-head { margin: 2.5rem 0 0; }

@media (min-width: 40rem) {
  .hero { margin-top: 4rem; }
  .page-head { margin-top: 3.25rem; }
}

h1 {
  margin: 0;
  color: var(--emph);
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: 0.01em;
  overflow-wrap: break-word;
}

/* 22ch, and one rule for both languages: ch is font-relative, so it means 22
   characters whatever the face, and both headlines are written to break inside it.

   English: "Android and web apps," is 21 characters and fits; "built" would make
   27 and does not, so the line breaks after the comma and "built end to end." (17)
   follows. Ukrainian: "Android і веб —" is 15 and fits; the next unit would make
   24, so it breaks at the dash and "від коду до релізу." (19) follows. That unit
   is one piece because the two prepositions are bound to their nouns with nbsp —
   neither can be orphaned at a line end if the headline is ever re-measured.

   The clamp floor is 1.5rem rather than the design's 1.875rem for the narrow case:
   a 320px window leaves the sheet 288px, which at 24px in this 0.6em face holds 20
   characters. The English headline takes three lines there, the Ukrainian two, and
   the longest single unit needs 144px of the 288 — nothing overflows. */
.hero h1 { font-size: clamp(1.5rem, 7vw, 3rem); max-width: 22ch; }

.page-head h1 { font-size: clamp(1.75rem, 6vw, 2.5rem); }

.lede {
  margin: 1.5rem 0 0;
  max-width: 46ch;
  font-size: 1.3125rem;
  line-height: 1.45;
}

strong, b {
  font-weight: 400;
  color: var(--emph);
}

/* Framed blocks */

.ident,
.record,
.contact {
  border: 2px solid var(--edge);
  background: var(--paper);
}

.ident {
  margin: 1.75rem 0 0;
  padding: 1rem 1.125rem;
  max-width: 34rem;
}

.ident p {
  display: flex;
  gap: 0.75rem;
  margin: 0;
  font-size: 1.1875rem;
  line-height: 1.45;
}

.ident p::before {
  content: "";
  flex: none;
  width: 0.5rem;
  height: 0.5rem;
  margin-top: 0.5rem;
  background: var(--marker);
}

/* Text inside a frame steps up from --muted to --ink: the panel is darker than
   the page, and the brighter grey keeps that pairing well past AA. */
.ident .quiet {
  margin-top: 0.375rem;
  color: var(--ink);
  font-size: 1.0625rem;
}

.ident .quiet::before { background: transparent; }

/* Sections */

section { margin-top: 3.25rem; }

@media (min-width: 40rem) {
  section { margin-top: 4rem; }
}

h2 {
  display: flex;
  align-items: baseline;
  gap: 0.625rem;
  margin: 0 0 1.25rem;
  color: var(--emph);
  font-size: 1.5rem;
  font-weight: 400;
  line-height: 1.3;
}

h2::before {
  content: "";
  flex: none;
  width: 0.625rem;
  height: 0.625rem;
  background: var(--marker);
}

/* 58ch, not the 62ch this held while the face was half an em wide: at 0.6em, 62
   characters need 744px and the sheet offers 704, so the container did the capping
   and the rule said nothing. 58ch is what actually fits, so the measure is stated
   where it can be read rather than left to fall out of the layout. */
p { max-width: 58ch; }

/* A long url must wrap rather than run past its box. */
p, li, dd, a { overflow-wrap: break-word; }

.prose { margin: 0 0 1rem; }

.hero .prose { margin-top: 1.25rem; }

.prose:last-child { margin-bottom: 0; }

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

/* Rows: areas of work, members, the legal record */

/* Separators sit between rows, not around them. A border on the block plus one
   under every row drew a line above the first row and below the last as well, so a
   three-row block took four lines to show two divisions, and the single row on
   /members took two lines to show none — which also put a second rule 48px from
   the one .onward draws, reading as a mistake. Measured per page, the horizontal
   lines went 6->4 on the home page, 11->9 on /about, 7->5 on /products and 5->3 on
   /members. */
.rows { margin: 0; }

.row { padding: 1.125rem 0; }

.row + .row { border-top: 2px solid var(--rule); }

@media (min-width: 40rem) {
  .rows.split .row {
    display: grid;
    grid-template-columns: 14rem minmax(0, 1fr);
    gap: 0 1.5rem;
    align-items: baseline;
  }

  /* The label owns column one; everything else stacks in column two, however
     many paragraphs a row carries. */
  .rows.split .row > *:not(h3):not(dt) { grid-column: 2; }
}

/* The member's portrait, and the block it shares with the name. Pixel art on an
   80x93 grid at 32 colours taken from the photograph itself, drawn as paths rather
   than one rect per cell — greedy 2D merging turns 7440 cells into 3884 rectangles,
   and path data rather than rect elements keeps that to 53KB. It is linked rather
   than inlined like the logo: it carries its own colours and has no palette to
   follow, and one file serves both languages.

   The grid is 93 rows rather than the 120 it started at because the row's two
   columns have to reconcile their heights: at 120 the portrait block stood 372px
   against 227px of prose and left 145px of nothing beside the text. Cropping to 88
   brings it to 284px — a 57px difference, which reads as the row's own spacing
   rather than as a hole. Shrinking the width instead would have cost the detail the
   grid was raised for.

   The window is rows 15 to 108 of the 120, not the top of the frame: taken from the
   top the head floated with empty background above it and the collar was cut at the
   chin. Sliding the window down traded that headroom for the collar and shoulder,
   which gives the head a base to sit on; the five rows back above the crown are
   what keeps it from touching the frame.

   Recolouring it in the site's own tokens was tried and rejected on sight. Do not
   try it again without showing it to someone first: it harmonises on paper and
   looks dead.

   What keeps the cells hard-edged is shape-rendering="crispEdges" inside the file,
   not anything here. image-rendering: pixelated was tried and measured: against
   image-rendering: auto it changed 0 pixels of the render, because the property
   applies to raster images and this is vector content the browser draws at the
   final size. Dropping crispEdges from the file, by contrast, changed 18777 — so
   that attribute is the load-bearing one, and it lives in the SVG.

   The width and the grid are still chosen together. Cells have to be big enough to
   see: at 14rem, which is exactly the label column, 80 across come out at 2.8px
   each — detailed enough for the face, coarse enough to still read as pixel art.
   Raising the grid without raising the width only trades one for the other. */

.member .portrait {
  display: block;
  width: 14rem;
  height: auto;
  margin: 0 0 0.75rem;
  border: 2px solid var(--edge);
  background: var(--paper);
}

/* Beats .rows.split .row > *:not(h3):not(dt), which would send this to column two:
   four classes against that rule's three. The name is inside, so column one holds
   the portrait and the name together and the prose keeps column two to itself.

   The prose needs its own wrapper for the same reason: left as two loose
   paragraphs they became two grid items in two grid rows, and the first row was as
   tall as the portrait, which opened a gap of a hundred-odd pixels between them.
   As one item they flow. */
@media (min-width: 40rem) {
  .rows.split .row > .member {
    grid-column: 1;
    align-self: start;
  }
}

.member-text p:last-child { margin-bottom: 0; }

.row h3 {
  margin: 0 0 0.5rem;
  color: var(--emph);
  font-size: 1.25rem;
  font-weight: 400;
  line-height: 1.3;
}

@media (min-width: 40rem) {
  .rows.split .row h3 { margin-bottom: 0; }
}

.row p { margin: 0 0 0.625rem; color: var(--muted); }

.row p:last-child { margin-bottom: 0; }

dt {
  color: var(--ink);
  font-size: 1.125rem;
}

dd { margin: 0; overflow-wrap: anywhere; }

/* Flat fact list */

.facts {
  margin: 0 0 1.75rem;
  padding: 0;
  list-style: none;
}

.facts li {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.75rem 0;
  color: var(--muted);
}

.facts li + li { border-top: 2px solid var(--rule); }

.facts li::before {
  content: "";
  flex: none;
  width: 0.5rem;
  height: 0.5rem;
  background: var(--marker);
}

/* The registration record: the same frame, holding a definition list */

.record {
  margin-top: 1.5rem;
  padding: 1.25rem 1.25rem 0.25rem;
}

@media (min-width: 40rem) {
  .record { padding: 1.75rem 1.75rem 0.5rem; }
}

.record .rows { border-top: none; }

.record .row:last-child { border-bottom: none; }

/* Call to action */

.cta {
  display: inline-block;
  margin-top: 1.75rem;
  padding: 0.6875rem 1.125rem;
  border: 2px solid var(--edge);
  background: var(--paper);
  color: var(--emph);
  font-size: 1.1875rem;
  text-decoration: none;
}

.cta:hover {
  background: var(--emph);
  color: var(--ground);
}

/* Contact panel */

.contact {
  margin-top: 3.25rem;
  padding: 1.5rem 1.25rem;
}

@media (min-width: 40rem) {
  .contact { margin-top: 4rem; padding: 2rem; }
}

.contact-mail {
  display: inline-block;
  margin: 0 0 0.875rem;
  font-size: clamp(1.375rem, 6vw, 2rem);
  line-height: 1.25;
  overflow-wrap: anywhere;
}

.contact p { margin: 0; max-width: 48ch; color: var(--ink); }

/* Links */

a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.2em;
}

a:hover { color: var(--emph); }

a:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

/* Next-page links at the foot of a page */

.onward {
  margin-top: 3rem;
  padding-top: 1.25rem;
  border-top: 2px solid var(--edge);
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 2rem;
  font-size: 1.1875rem;
}

/* Footer */

footer {
  margin-top: 2.5rem;
  padding-top: 1rem;
  border-top: 2px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.25rem 1.5rem;
  font-size: 1.0625rem;
  color: var(--muted);
}

footer p { margin: 0; }
