/* PhoneForge brand tokens and page chrome.
 *
 * One file, loaded by every web client and by the marketing site, so that
 * "the same green on every page" is a fact about the code rather than a
 * thing somebody has to remember.
 *
 * The brand is two colours: white, and the dark green the mark is drawn in.
 * The ramp below is Tailwind's emerald, unmodified. That is not laziness: the
 * logo's green is oklch hue 164.1 and emerald is 163.2, so they are already
 * the same colour. The contacts app styles 313 elements with emerald-*
 * utilities and they line up with the mark for free.
 *
 * An earlier version of this file shifted the whole ramp to hue 149.8, taken
 * from the anvil mark that was on the live server. That mark is not the logo.
 * See docs/logo_designs/ before changing any of this.
 *
 * Measured against white:
 *    600  3.65:1   large text and borders only
 *    700  5.36:1   body text
 *    800  7.61:1   buttons, headings
 *    950 15.18:1   ink
 * The mark's own #03986c is 3.68:1 on white: fine for a graphical object,
 * not for text.
 */

:root {
  --pf-green-50: #ecfdf5;
  --pf-green-100: #d0fae5;
  --pf-green-200: #a4f4cf;
  --pf-green-300: #5ee9b5;
  --pf-green-400: #00d492;
  --pf-green-500: #00bc7d;
  --pf-green-600: #009966;
  --pf-green-700: #007a55;
  --pf-green-800: #006045;
  --pf-green-900: #004f3b;
  --pf-green-950: #002c22;

  /* The mark's own green, from docs/logo_designs/pf_logo-2.png. */
  --pf-mark: #03986c;

  /* ---- Semantic tokens -------------------------------------------------
   *
   * Everything below is redefined for dark mode further down, so a rule
   * that uses a token follows the theme and a rule that hard-codes a hex
   * does not. That is the whole mechanism: there is no dark-mode rule for
   * each component, only one palette swapped underneath them.
   *
   * Every pair that carries meaning was measured in both modes before it
   * went in; the ratios in the comments are real, not aspirations. The
   * script is scripts/check_contrast.py and it runs in the parity check.
   */
  --pf-ink: var(--pf-green-950);
  --pf-paper: #ffffff;
  /* The page behind the cards. */
  --pf-surface: #f2f4f4;
  /* A card sitting on that page. */
  --pf-card: #ffffff;
  /* A panel inside a card: a tinted note, a result box. */
  --pf-tint: #f4f6f6;
  --pf-tint-line: #cbeade;
  /* A hairline between things. Decoration, not a boundary. */
  --pf-line: #dfe3e2;
  /* The edge of a control, which WCAG 1.4.11 does require to be visible.
     3.13:1 on white, 3.15:1 on the dark card. The old --pf-line was doing
     this job at 1.29:1. */
  --pf-line-strong: #619e7e;
  /* 5.77:1 on white: readable as secondary text, which --pf-green-600 at
     3.65:1 is not. */
  --pf-muted: #526b62;
  --pf-primary: var(--pf-green-800);
  --pf-primary-hover: var(--pf-green-900);
  --pf-on-primary: #ffffff;
  /* A dark pill on a light page, inverted in dark mode. */
  --pf-chip: #173f37;
  --pf-on-chip: #ffffff;
  /* A bar that is dark in BOTH modes: the top bar, the footer, the
     page-number pills. Using --pf-ink for these was fine while there
     was only one mode; in dark mode ink becomes near-white, so every
     one of them would have flipped to a white block with white text
     on it. */
  --pf-bar: var(--pf-green-950);
  --pf-on-bar: #ffffff;

  --pf-danger: #b42318;
  --pf-danger-soft: #fdeae5;
  --pf-warn: #8a5a10;
  --pf-warn-soft: #fdf6e7;
  --pf-warn-line: #f0cfc3;
  --pf-ok-soft: #e7f6ef;
  --pf-link: var(--pf-green-800);
  --pf-accent: var(--pf-green-600);

  --pf-radius: 12px;
  --pf-shell: 1120px;
  --pf-font: "Geist Variable", Inter, ui-sans-serif, system-ui, -apple-system,
    BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* ---- Dark mode ----------------------------------------------------------
 *
 * Two ways in, and they have to agree:
 *
 *   data-theme="dark"   the person chose it in Settings
 *   prefers-color-scheme  they chose it in their operating system and have
 *                         not overridden it here
 *
 * The media query is guarded by :not([data-theme="light"]) so that
 * choosing Light explicitly beats a dark OS. Without the guard, Light is
 * a setting that silently does nothing for exactly the people most likely
 * to look for it.
 *
 * shared/theme.js sets the attribute from <head>, before paint, so
 * switching pages does not flash white.
 *
 * Not pure black. A near-black carrying the brand's own hue reads as the
 * same product with the lights off, and pure black under bright text is
 * harsh on an OLED panel.
 */
:root[data-theme="dark"] {
  /* The surfaces are NEUTRAL, not green. They were green-dominant
     (paper #0a1410, surface #0d1a15, card #10201a, tint #16291f), which
     meant every page in the app was a green page. Green is this
     product's colour for CHROME: the bar, the primary, the accents,
     all still green below. It is not a colour to read a document on, a
     phonebook on, or a dashboard on. A trace of warmth is kept so the
     neutral does not read as cold blue-grey beside the green chrome. */
  --pf-ink: #e9ecec;              /* 16.71:1 on paper */
  --pf-paper: #121415;
  --pf-surface: #171a1b;
  --pf-card: #1c1f20;
  --pf-tint: #232728;
  --pf-tint-line: #3a3f40;
  --pf-line: #303536;
  --pf-line-strong: #47745c;      /* 3.15:1 on the card */
  --pf-muted: #adb5b3;            /* 8.41:1 on the card */
  --pf-primary: var(--pf-green-400);
  --pf-primary-hover: var(--pf-green-300);
  --pf-on-primary: #04120d;       /* 9.87:1 on the button */
  --pf-chip: var(--pf-green-300);
  --pf-on-chip: #0a1410;

  --pf-danger: #ff9d86;           /* 8.38:1 on the card */
  --pf-danger-soft: #2e1711;
  --pf-warn: #f5c26b;
  --pf-warn-soft: #2b2213;
  --pf-warn-line: #4a3a1c;
  --pf-ok-soft: #12301f;
  --pf-link: var(--pf-green-300); /* 11.10:1 on the card */
  --pf-accent: var(--pf-green-400);
  /* The bar lifts off the page rather than sinking into it:
     green-950 on a near-black paper is almost invisible. */
  --pf-bar: #16291f;
  --pf-on-bar: #ffffff;
  --pf-wordmark-forge: var(--pf-green-300);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --pf-ink: #e9ecec;
    --pf-paper: #121415;
    --pf-surface: #171a1b;
    --pf-card: #1c1f20;
    --pf-tint: #232728;
    --pf-tint-line: #3a3f40;
    --pf-line: #303536;
    --pf-line-strong: #47745c;
    --pf-muted: #adb5b3;
    --pf-primary: var(--pf-green-400);
    --pf-primary-hover: var(--pf-green-300);
    --pf-on-primary: #04120d;
    --pf-chip: var(--pf-green-300);
    --pf-on-chip: #0a1410;

    --pf-danger: #ff9d86;
    --pf-danger-soft: #2e1711;
    --pf-warn: #f5c26b;
    --pf-warn-soft: #2b2213;
    --pf-warn-line: #4a3a1c;
    --pf-ok-soft: #12301f;
    --pf-link: var(--pf-green-300);
    --pf-accent: var(--pf-green-400);
    --pf-bar: #16291f;
    --pf-on-bar: #ffffff;
    --pf-wordmark-forge: var(--pf-green-300);
  }
}

* {
  box-sizing: border-box;
}

/* The hidden attribute has to win.
 *
 * The browser's own rule for it is [hidden] { display: none }, which any
 * class selector that sets display beats on specificity. So
 * `.capture-start { display: flex }` kept the camera buttons on screen
 * after the viewfinder opened, with the attribute dutifully set and doing
 * nothing. Same shape of bug as `.hidden` in tools.css: easy to write,
 * invisible until you look.
 */
[hidden] {
  display: none !important;
}

/* A sticky bar covers whatever an in-page link jumps to, so every "#"
   target would land underneath it: the Pricing buttons point at
   /help/#contact, and the guide's contents are all anchors. This tells
   the browser to stop that much short. */
html {
  scroll-padding-top: 76px;
}

body {
  background: var(--pf-paper);
  color: var(--pf-ink);
  font-family: var(--pf-font);
  line-height: 1.6;
  margin: 0;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  line-height: 1.2;
  margin: 0 0 12px;
}

a {
  color: var(--pf-link);
}

button,
input,
select,
a {
  font-family: inherit;
}

/* Every interactive thing has to be reachable by keyboard and visibly so.
   The browser default outline disappears against a green button. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--pf-green-600);
  outline-offset: 2px;
}

.pf-skip {
  background: var(--pf-bar);
  border-radius: 0 0 var(--pf-radius) 0;
  color: var(--pf-on-bar);
  left: 0;
  padding: 10px 18px;
  position: absolute;
  top: -100px;
  z-index: 100;
}

.pf-skip:focus {
  top: 0;
}

/* "Explain what each tool does", off.
 *
 * Scoped deliberately narrowly. It hides the caption under a heading and
 * the lede under a page title, which are there to teach, and it leaves
 * .tool-privacy alone. Those notes say what happens to somebody's files;
 * a preference about reading comfort must not be able to switch off a
 * statement about their data, and anyone who reaches for this setting is
 * not asking for that.
 *
 * Set as a class on <html> by shared/prefs.js, so it covers captions a
 * client renders later as well as the ones in the markup.
 */
.pf-no-tips .panel-caption,
.pf-no-tips .tool-lede {
  display: none;
}

/* A label a screen reader reads and a sighted person does not need,
   because the control beside it already says what it is. Not
   display:none, which would take it out of the accessibility tree along
   with the layout. */
.pf-visually-hidden {
  border: 0;
  clip-path: inset(50%);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

/* ---- Wordmark ----------------------------------------------------------
 *
 * "PhoneForge" is set in real text, never baked into an image, because the
 * two halves take different colours and both have to invert against
 * whatever they sit on. A PNG can only be right on one background; this is
 * right on all of them, stays crisp at any size, and is readable by a
 * screen reader and a search engine.
 *
 * Phone is the ink colour, Forge is the green. Measured:
 *
 *   on white          Phone 15.18:1   Forge 5.36:1
 *   on the footer     Phone 14.41:1   Forge 5.09:1
 *   on the dark bar   Phone 15.18:1   Forge 9.97:1
 *
 * Forge is deliberately not the mark's own #03986c, which is 3.68:1 on
 * white: fine for a graphic, too weak for a word.
 */

.pf-wordmark {
  font-weight: 650;
  letter-spacing: -0.005em;
  white-space: nowrap;
}

.pf-wordmark .pf-word-phone {
  color: var(--pf-wordmark-phone, var(--pf-ink));
}

.pf-wordmark .pf-word-forge {
  color: var(--pf-wordmark-forge, var(--pf-green-700));
}

/* The wordmark follows the SURFACE it sits on, not the operating system's
   theme, and that distinction still matters now that the tool clients have
   a dark mode.

   The top bar and the footer are dark in BOTH modes (--pf-bar), so the
   wordmark on them is white and green-300 whatever the theme is. Keying
   this off prefers-color-scheme instead was the original bug: it painted
   the footer's "Phone" white on pale green, 1.08:1, invisible. The surface
   is the thing that decides, so the surface is what the rule names. */
.pf-topbar,
.pf-on-dark {
  --pf-wordmark-phone: #ffffff;
  --pf-wordmark-forge: var(--pf-green-300);
}

/* ---- Top bar ------------------------------------------------------------ */

/* Sticky, so the tools and the search stay reachable without scrolling
   back to the top of a long guide article or pricing page.

   z-index 90 sits above the page and below the two things that must
   never be covered: the skip link (100), which is the keyboard way in,
   and the search overlay (200). The bar's own dropdowns (60, 70, 80)
   are its children, so they ride inside this stacking context and do
   not need raising.

   Nothing above this in the tree may set overflow, which silently
   turns sticky back into static. */
.pf-topbar {
  align-items: center;
  background: var(--pf-bar);
  display: flex;
  flex-wrap: wrap;
  gap: 12px 24px;
  justify-content: space-between;
  padding: 10px 24px;
  position: sticky;
  top: 0;
  z-index: 90;
}

.pf-brand {
  align-items: center;
  color: #ffffff;
  display: flex;
  font-size: 17px;
  font-weight: 650;
  gap: 10px;
  text-decoration: none;
}

.pf-brand img {
  display: block;
  height: 34px;
  object-fit: contain;
  width: 34px;
}

.pf-brand b {
  font-weight: 650;
}

.pf-brand .pf-wordmark {
  font-size: inherit;
}

/* The product name, so a page says which forge you are in without a heading. */
.pf-brand .pf-product {
  border-left: 1px solid rgba(255, 255, 255, 0.28);
  color: var(--pf-green-300);
  font-weight: 600;
  margin-left: 4px;
  padding-left: 12px;
}

.pf-switch {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.pf-switch a {
  align-items: center;
  border-radius: 999px;
  color: rgba(255, 255, 255, 0.82);
  display: inline-flex;
  font-size: 14.5px;
  gap: 7px;
  /* 44px is the touch-target floor; these sit in a phone's thumb reach. */
  min-height: 44px;
  padding: 0 14px;
  text-decoration: none;
}

.pf-switch a:hover {
  background: rgba(255, 255, 255, 0.1);
  color: #ffffff;
}

.pf-switch a[aria-current="page"] {
  background: var(--pf-green-700);
  color: #ffffff;
  font-weight: 600;
}

.pf-switch svg {
  height: 17px;
  width: 17px;
}

/* ---- Account control ----------------------------------------------------
 *
 * Settings, Profile and Storage behind one button at the end of the bar.
 * The mobile app puts them behind a kebab for the same reason: they are
 * the screens you go looking for, not the ones you arrive for, and three
 * more entries in the switcher would push Cleaner off a phone's first row.
 */

.pf-bar-end {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* ---- Tools menu ---------------------------------------------------------
 *
 * Four tools behind one control, with a card that says what each is
 * for. A flat list of seven destinations wrapped onto two rows before
 * a phone was anywhere near, and a menu of four bare nouns tells
 * somebody who has not used them anything they did not get from the
 * word Tools.
 */

/* The ToolBox is a split control: a link to /tools/ and a caret that
 * opens the menu, drawn as one pill. The highlight sits on the wrapper
 * so that hovering either half lights the whole thing, rather than the
 * pill appearing to come apart under the pointer. */
.pf-menu {
  align-items: center;
  border-radius: 999px;
  display: inline-flex;
  position: relative;
}

.pf-menu:hover,
.pf-menu:focus-within,
.pf-menu.is-open {
  background: rgba(255, 255, 255, 0.1);
}

.pf-menu.is-current {
  background: var(--pf-green-700);
}

.pf-menu.is-current .pf-menu-btn {
  color: #ffffff;
  font-weight: 600;
}

.pf-menu-btn {
  align-items: center;
  background: none;
  border: 0;
  border-radius: 999px;
  color: rgba(255, 255, 255, 0.82);
  cursor: pointer;
  display: inline-flex;
  font: inherit;
  font-size: 14.5px;
  gap: 7px;
  min-height: 44px;
  padding: 0 14px;
  text-decoration: none;
}

.pf-menu:hover .pf-menu-btn,
.pf-menu:focus-within .pf-menu-btn,
.pf-menu.is-open .pf-menu-btn {
  color: #ffffff;
}

/* The halves meet, so the label loses its right padding and the caret
 * its left: together they still measure one pill. */
.pf-menu-open {
  padding-right: 6px;
}

.pf-menu-caret {
  gap: 0;
  padding-left: 4px;
  padding-right: 12px;
}

.pf-menu-btn svg {
  height: 16px;
  width: 16px;
}

/* Scoped to the caret. The label is a link with a single icon, which
 * is also its :last-child, so an unscoped rule shrank the grid mark. */
.pf-menu-caret svg {
  height: 14px;
  transition: transform 0.15s ease;
  width: 14px;
}

.pf-menu-caret[aria-expanded="true"] svg {
  transform: rotate(180deg);
}

/* A grid, not a column. Six tools stacked one per row made a menu
 * taller than some laptop screens, and read as a list of links rather
 * than as a set of tools you choose between. */
.pf-menu-card {
  background: var(--pf-card);
  border: 1px solid var(--pf-line);
  border-radius: 14px;
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.28);
  column-gap: 2px;
  display: grid;
  grid-template-columns: repeat(2, minmax(238px, 1fr));
  left: 0;
  padding: 8px;
  position: absolute;
  top: calc(100% + 8px);
  z-index: 70;
}

@media (min-width: 1180px) {
  .pf-menu-card {
    grid-template-columns: repeat(3, minmax(232px, 1fr));
  }
}

/* Hung from the right edge when the button sits near the right of the
 * bar and a left-anchored card would run off the screen. Set by
 * measurement in shell.js, because which edge is correct depends on
 * where the bar put the button. */
.pf-menu-card.is-right {
  left: auto;
  right: 0;
}

.pf-menu-card a {
  align-items: flex-start;
  border-radius: 10px;
  color: var(--pf-ink);
  display: flex;
  gap: 11px;
  padding: 10px 12px;
  text-decoration: none;
}

.pf-menu-card a:hover,
.pf-menu-card a:focus-visible {
  background: var(--pf-surface);
}

.pf-menu-card a[aria-current="page"] {
  background: var(--pf-tint);
}

.pf-menu-icon {
  align-items: center;
  background: var(--pf-tint);
  border-radius: 9px;
  color: var(--pf-primary);
  display: flex;
  flex: none;
  height: 34px;
  justify-content: center;
  width: 34px;
}

.pf-menu-icon svg {
  height: 17px;
  width: 17px;
}

.pf-menu-card b {
  display: block;
  font-size: 14.5px;
}

.pf-menu-card small {
  color: var(--pf-muted);
  display: block;
  font-size: 12.5px;
  line-height: 1.45;
}

/* Full width under the grid, whatever the column count. */
.pf-menu-all {
  align-items: center;
  border-top: 1px solid var(--pf-line);
  color: var(--pf-link) !important;
  font-size: 13.5px;
  font-weight: 650;
  grid-column: 1 / -1;
  justify-content: space-between;
  margin-top: 6px;
  padding-top: 12px !important;
}

.pf-menu-all svg {
  height: 15px;
  width: 15px;
}

/* ---- Narrow screens -----------------------------------------------------
 *
 * Everything but the brand goes behind one button. The bar used to
 * wrap to a second and then a third row, which on a phone pushed the
 * page itself below the fold.
 */

.pf-burger {
  align-items: center;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 10px;
  color: #ffffff;
  cursor: pointer;
  display: none;
  height: 42px;
  justify-content: center;
  width: 42px;
}

.pf-burger svg {
  height: 20px;
  width: 20px;
}

@media (max-width: 900px) {
  .pf-topbar {
    flex-wrap: nowrap;
    padding: 10px 16px;
  }

  .pf-burger {
    display: inline-flex;
  }

  .pf-bar-end {
    background: var(--pf-bar);
    border-top: 1px solid rgba(255, 255, 255, 0.12);
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    left: 0;
    padding: 10px 16px 16px;
    position: absolute;
    right: 0;
    top: 100%;
    z-index: 80;
  }

  .pf-bar-end.is-open {
    display: flex;
  }

  /* This used to say position: relative, to anchor the open burger
     panel below. Sticky is also a positioned ancestor, so the panel
     still anchors here, and overriding it would have un-stuck the bar
     on exactly the screens where a fixed bar helps most. */

  .pf-switch {
    align-items: stretch;
    flex-direction: column;
  }

  .pf-menu {
    flex-wrap: wrap;
    width: 100%;
  }

  .pf-menu-btn {
    justify-content: flex-start;
  }

  /* The label takes the row and the caret sits at its end, so the
     drawer reads as one line you can either follow or expand. */
  .pf-menu-open {
    flex: 1;
  }

  /* In the drawer the card is just part of the list: a floating
     panel inside a panel is a popup inside a popup. One column,
     because the drawer is as wide as a phone. */
  .pf-menu-card {
    background: none;
    border: 0;
    box-shadow: none;
    grid-template-columns: 1fr;
    min-width: 0;
    padding: 0 0 0 14px;
    position: static;
    width: 100%;
  }

  .pf-menu-card a {
    color: rgba(255, 255, 255, 0.85);
  }

  .pf-menu-card a:hover,
  .pf-menu-card a:focus-visible,
  .pf-menu-card a[aria-current="page"] {
    background: rgba(255, 255, 255, 0.1);
  }

  .pf-menu-card b {
    color: #ffffff;
  }

  .pf-menu-card small {
    color: rgba(255, 255, 255, 0.6);
  }

  .pf-menu-all {
    border-top-color: rgba(255, 255, 255, 0.15);
    color: var(--pf-green-300) !important;
  }

  .pf-menu-icon {
    background: rgba(255, 255, 255, 0.1);
    color: var(--pf-green-300);
  }

  .pf-account {
    margin-top: 4px;
  }

  .pf-account-btn {
    border-radius: 10px;
    justify-content: flex-start;
    padding: 0 12px;
    width: 100%;
  }

  .pf-account-btn::after {
    content: "Your account";
    font-size: 14.5px;
    margin-left: 10px;
  }

  .pf-account-menu {
    background: none;
    border: 0;
    box-shadow: none;
    padding: 0 0 0 14px;
    position: static;
  }

  .pf-account-menu a {
    color: rgba(255, 255, 255, 0.85);
  }

  .pf-account-menu a:hover {
    background: rgba(255, 255, 255, 0.1);
  }
}

/* ---- Search -------------------------------------------------------------
 *
 * A way into everything, so it sits at the head of the bar rather than
 * among the tools. The word is hidden on a phone, where the bar has no
 * room for it and the icon is unambiguous.
 */

.pf-account {
  position: relative;
}

.pf-account-btn {
  align-items: center;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 999px;
  color: rgba(255, 255, 255, 0.88);
  cursor: pointer;
  display: inline-flex;
  height: 40px;
  justify-content: center;
  padding: 0;
  width: 40px;
}

.pf-account-btn:hover,
.pf-account-btn[aria-expanded="true"] {
  background: rgba(255, 255, 255, 0.2);
  color: #ffffff;
}

.pf-account-btn svg {
  height: 19px;
  width: 19px;
}

.pf-account-menu {
  background: var(--pf-card);
  border: 1px solid var(--pf-line);
  border-radius: 12px;
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.22);
  min-width: 190px;
  overflow: hidden;
  padding: 5px;
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  z-index: 60;
}

.pf-account-menu a {
  align-items: center;
  border-radius: 8px;
  color: var(--pf-ink);
  display: flex;
  font-size: 14.5px;
  gap: 10px;
  min-height: 42px;
  padding: 0 12px;
  text-decoration: none;
}

.pf-account-menu a:hover,
.pf-account-menu a:focus-visible {
  background: var(--pf-surface);
}

.pf-account-menu a[aria-current="page"] {
  color: var(--pf-link);
  font-weight: 650;
}

.pf-account-menu svg {
  height: 17px;
  flex: none;
  width: 17px;
}

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

/* The footer is dark, like the bar at the top.
 *
 * It used the same pale green as the page, so there was no edge: the
 * content simply stopped and some links appeared. Bookending the page
 * between two dark bands says where it ends without a rule across the
 * screen, and it stops the footer competing with the work above it. */
.pf-footer {
  background: var(--pf-bar);
  color: rgba(255, 255, 255, 0.78);
  margin-top: 64px;
  padding: 12px 24px;
}

/* One row, kept short: the wordmark and its line on the left, the four
 * category columns beside it with every link visible. The height comes
 * off the link rows and the padding, not from hiding anything behind a
 * click. Every gap in the row is the same 48px — the brand is one of
 * the blocks, not a separate zone, so the space beside it matches the
 * spaces between the categories. */
.pf-footer-inner {
  align-items: stretch;
  display: flex;
  flex-wrap: wrap;
  gap: 12px 48px;
  justify-content: flex-start;
  margin: 0 auto;
  max-width: var(--pf-shell);
}

/* On the dark footer the wordmark takes the same two colours as the one
   in the top bar; see the --pf-wordmark-* variables. */
.pf-footer {
  --pf-wordmark-phone: #ffffff;
  --pf-wordmark-forge: var(--pf-green-300);
}

.pf-footer-brand {
  align-items: flex-start;
  display: flex;
  flex: 0 1 300px;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

.pf-footer-wordmark {
  align-items: center;
  display: inline-flex;
  flex-shrink: 0;
  font-size: 17px;
  gap: 10px;
  text-decoration: none;
}

.pf-footer-brand img {
  display: block;
  height: 40px;
  object-fit: contain;
  width: 40px;
}

/* The tagline travels with the wordmark, stacked beneath it on the left
 * of the row. It wraps inside its column; it does not drive the row
 * height, the tallest category column does. */
.pf-footer-tagline {
  color: rgba(255, 255, 255, 0.64);
  font-size: 12.5px;
  line-height: 1.45;
  margin: 0;
}

/* The four categories sit beside the wordmark as columns, heading over
 * an open list. Nothing expands: the links are the footer working. The
 * column gap matches the row gap, so every space in the band reads the
 * same. */
.pf-footer-cats {
  display: flex;
  flex: 0 1 auto;
  flex-wrap: wrap;
  gap: 12px 48px;
}

.pf-footer-cat h2 {
  color: #ffffff;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
  margin: 0 0 4px;
  text-transform: uppercase;
}

.pf-footer ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.pf-footer li {
  margin: 0;
}

.pf-footer li a,
.pf-footer li span,
.pf-footer li button {
  align-items: center;
  /* 8.6:1 on the ink background. */
  color: rgba(255, 255, 255, 0.74);
  display: inline-flex;
  font-size: 13.5px;
  gap: 6px;
  min-height: 26px;
  text-decoration: none;
}

.pf-footer li a:hover {
  color: #ffffff;
  text-decoration: underline;
}

/* A product whose domain is not answering yet. Shown, because the network is
   the point, but not linked, because a dead link in a footer is worse than
   no link. Delete the class and add the href when the site goes up. */
.pf-footer li .pf-soon {
  color: rgba(255, 255, 255, 0.5);
  cursor: default;
}

.pf-soon-tag {
  background: rgba(255, 255, 255, 0.14);
  border-radius: 999px;
  color: var(--pf-green-300);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 1px 7px;
  text-transform: uppercase;
}

.pf-footer-base {
  border-top: 1px solid rgba(255, 255, 255, 0.16);
  color: rgba(255, 255, 255, 0.6);
  display: flex;
  flex-wrap: wrap;
  font-size: 13px;
  gap: 8px 20px;
  justify-content: space-between;
  margin: 10px auto 0;
  max-width: var(--pf-shell);
  padding-top: 10px;
}

.pf-footer-base a {
  color: rgba(255, 255, 255, 0.78);
}

.pf-footer-base p {
  margin: 0;
}

@media (max-width: 900px) {
  /* Narrower gaps, still uniform across the row; the categories just
   * wrap onto however many lines they need. */
  .pf-footer-inner {
    gap: 12px 32px;
  }

  .pf-footer-cats {
    gap: 12px 32px;
  }
}

@media (max-width: 700px) {
  /* The brand takes a line of its own; the categories wrap below it. */
  .pf-footer-brand {
    flex-basis: 100%;
  }
}

@media (max-width: 560px) {
  .pf-topbar {
    padding: 10px 16px;
  }

  .pf-footer {
    padding: 10px 16px;
  }

  .pf-footer-inner {
    gap: 12px 24px;
  }

  .pf-footer-cats {
    gap: 12px 24px;
  }
}

/* ---- Segmented control --------------------------------------------------
 *
 * Two or three exclusive choices, shown together because the comparison
 * is the point: the theme picker, and the scanner's PDF-or-images. It
 * lives here rather than in account.css because a tool page does not
 * load that file, and a control with no stylesheet is two bare buttons.
 *
 * aria-pressed is the single source of truth for which one is on, so
 * the look cannot drift from what a screen reader is told.
 */

.pf-seg {
  background: var(--pf-surface);
  border: 1px solid var(--pf-line);
  border-radius: 999px;
  display: inline-flex;
  flex: none;
  gap: 2px;
  padding: 3px;
}

.pf-seg button {
  background: none;
  border: 0;
  border-radius: 999px;
  color: var(--pf-muted);
  cursor: pointer;
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  min-height: 34px;
  padding: 0 14px;
}

.pf-seg button:hover:not([aria-pressed="true"]) {
  color: var(--pf-ink);
}

.pf-seg button[aria-pressed="true"] {
  background: var(--pf-primary);
  color: var(--pf-on-primary);
}

/* ---- A destructive button ------------------------------------------------
 *
 * Outlined rather than filled: a solid red button beside a solid green
 * one reads as the other half of a pair, and this is not a choice
 * between two things.
 *
 * Here rather than in account.css, which is the layer only the account
 * pages load. Files and the document editor both use this class and
 * neither loads that file, so their Discard buttons had been rendering
 * as ordinary grey ones. Same mistake as the segmented control.
 */

.secondary-btn.is-danger {
  border-color: var(--pf-danger);
  color: var(--pf-danger);
}

.secondary-btn.is-danger:hover:not(:disabled) {
  background: var(--pf-danger-soft);
}

/* ---- Cookie and storage consent ----------------------------------------
 *
 * Bottom sheet rather than a full-screen overlay. The question is small
 * and honest, and blocking the whole page for it would be theatre.
 * z-index 150 puts it above the sticky bar (90) and below the search
 * overlay (200), which should still be able to cover it.
 */

.pf-consent {
  bottom: 0;
  display: flex;
  justify-content: center;
  left: 0;
  padding: 16px;
  position: fixed;
  right: 0;
  z-index: 150;
}

.pf-consent-card {
  background: var(--pf-card);
  border: 1px solid var(--pf-line);
  border-radius: var(--pf-radius);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.28);
  color: var(--pf-ink);
  max-height: 80vh;
  max-width: 560px;
  overflow-y: auto;
  padding: 20px;
  width: 100%;
}

.pf-consent-title {
  font-size: 17px;
  margin: 0 0 8px;
}

.pf-consent-text {
  color: var(--pf-muted);
  font-size: 14px;
  line-height: 1.55;
  margin: 0 0 16px;
}

.pf-consent-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 16px;
}

/* All three buttons share a size and weight on purpose. A small grey
   "manage preferences" beside a large coloured "Accept" is a choice in
   name only, and the whole point of this is that the choice is real. */
.pf-consent-btn {
  background: var(--pf-paper);
  border: 1px solid var(--pf-line);
  border-radius: 10px;
  color: var(--pf-ink);
  cursor: pointer;
  flex: 1 1 auto;
  font: inherit;
  font-weight: 600;
  min-height: 44px;
  padding: 0 14px;
}

.pf-consent-btn:hover {
  border-color: var(--pf-green-700);
}

.pf-consent-btn.is-primary {
  background: var(--pf-primary);
  border-color: var(--pf-primary);
  color: #ffffff;
}

.pf-consent-row {
  align-items: flex-start;
  border-top: 1px solid var(--pf-line);
  display: flex;
  gap: 14px;
  justify-content: space-between;
  padding: 14px 0;
}

.pf-consent-row-text strong {
  display: block;
  margin-bottom: 2px;
}

.pf-consent-row-text small {
  color: var(--pf-muted);
  display: block;
  font-size: 13px;
  line-height: 1.5;
}

.pf-consent-box {
  flex: none;
  height: 22px;
  margin-top: 2px;
  width: 22px;
}

.pf-consent-box:disabled {
  /* Essential is on and stays on. Shown rather than hidden, because
     "you cannot turn this off" is information people are entitled to. */
  opacity: 0.55;
}

@media (max-width: 560px) {
  .pf-consent {
    padding: 0;
  }

  .pf-consent-card {
    border-bottom: 0;
    border-radius: var(--pf-radius) var(--pf-radius) 0 0;
    max-height: 88vh;
  }

  .pf-consent-btn {
    flex: 1 1 100%;
  }
}

/* A footer entry that opens a dialog rather than navigating. Styled to
   match the links beside it: it belongs in that list, and making it look
   like a button would imply it does something different in kind. */
.pf-footer-link {
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
  font: inherit;
  padding: 0;
  text-align: left;
  text-decoration: none;
}

.pf-footer-link:hover {
  text-decoration: underline;
}

/* ---- Breadcrumbs -------------------------------------------------------
 *
 * So a subpage says what it is a subpage OF. /account/profile/ and
 * /account/settings/ are siblings in the URL and parent and child in the
 * product, and nothing on the page said which.
 */

.pf-crumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
}

.pf-crumbs li {
  align-items: center;
  color: var(--pf-muted);
  display: flex;
  font-size: 13.5px;
  gap: 6px;
}

/* The separator is generated, so it is never read out as content and
   never copied when somebody selects the trail. */
.pf-crumbs li + li::before {
  color: var(--pf-line);
  content: "/";
}

.pf-crumbs a {
  color: var(--pf-green-700);
}

.pf-crumbs [aria-current="page"] {
  color: var(--pf-ink);
  font-weight: 600;
}

/* ---- Language switcher --------------------------------------------------
 *
 * In the bar, between Your Guide and the account button: the last
 * control in the row that is about the whole app rather than about one
 * tool, and the first place somebody reading the wrong language looks.
 *
 * TEXT CODES, NOT FLAGS. A flag is a country and a language is not.
 * The French tricolore shown to a reader in Dakar or Douala, or the
 * Union Jack shown to one in Lagos or Accra, says this product belongs
 * to somebody else - which for a pan-African feed is exactly the wrong
 * signal, and wrong in both of the languages actually shipped.
 *
 * It sits on the dark bar in both themes, like everything else in
 * .pf-bar-end, so its colours are rgba on white rather than tokens.
 */
.pf-lang {
  align-items: center;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 999px;
  display: inline-flex;
  gap: 2px;
  min-height: 40px;
  padding: 0 5px 0 10px;
}

.pf-lang > svg {
  color: rgba(255, 255, 255, 0.65);
  height: 16px;
  margin-right: 3px;
  width: 16px;
}

.pf-lang-btn {
  background: transparent;
  border: 0;
  border-radius: 999px;
  color: rgba(255, 255, 255, 0.7);
  cursor: pointer;
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  min-height: 28px;
  padding: 0 9px;
}

.pf-lang-btn:hover {
  color: #ffffff;
}

.pf-lang-btn[aria-pressed="true"] {
  background: rgba(255, 255, 255, 0.92);
  color: var(--pf-green-950);
}

.pf-lang-btn:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 1px;
}

/* In the burger panel the row goes full width like the other entries,
   with the control pushed to the right so the codes line up with the
   chevrons above them. */
@media (max-width: 900px) {
  .pf-lang {
    align-self: stretch;
    justify-content: flex-end;
    margin-top: 6px;
  }
}
