/* Shared by every page: font, colours, buttons, form fields.
   Colour rule: neutral page, one cobalt accent. The contact cards bring the other colours.
   Shape rule: buttons and chips are full pills, panels are 1.25rem, inputs are 0.75rem. */
@font-face {
  font-family: "Figtree";
  src: url("fonts/figtree.woff2") format("woff2");
  font-weight: 300 900;
  font-display: swap;
}

/* Light for everyone by default. theme.js puts data-theme="dark" on <html> when the visitor
   switches. The phone that shows a card stays light, like the card pages themselves. */
:root,
.phone-screen {
  color-scheme: light;
  --bg: #f6f6f8;
  --surface: #fdfdfe;
  --ink: #0d0f15;
  --muted: #5b6172;
  --line: #e2e4ea;
  --tint: #ebeefb; /* a breath of the accent, for panels */
  --accent: #2450e6;
  --accent-hover: #1b3fc0;
  --accent-text: #2450e6; /* the accent when it is text on the page */
  --danger: #c8321f;
  --good: #0c6b35; /* a card that is online. Dark enough to be read as small text on its own tint (5:1) */
  --warn: #8a4d00; /* a card that is not online yet. The same */
  --focus: var(--accent-text);
  --r-panel: 1.25rem;
  --r-input: 0.75rem;
  --shadow: 0 1px 2px rgb(13 15 21 / 0.05), 0 10px 30px rgb(13 15 21 / 0.07);
  --sans: "Figtree", ui-sans-serif, system-ui, sans-serif;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0b0c10;
  --surface: #15171d;
  --ink: #f1f2f5;
  --muted: #a3a9b8;
  --line: #272b36;
  --tint: #121831;
  --accent-text: #8fa8ff;
  --danger: #ff8a75;
  --good: #4cc38a;
  --warn: #f0b95a;
  --shadow: 0 1px 2px rgb(0 0 0 / 0.4), 0 10px 30px rgb(0 0 0 / 0.35);
}

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 1rem/1.5 var(--sans);
  -webkit-font-smoothing: antialiased;
}

/* The HTML is in English. For a visitor in another language, lang.js puts i18n-wait on <html> and
   the page stays unseen until i18n.js has translated it and taken the class away. If the scripts
   never get there, the animation shows the page (in English) after 1.5 s. */
.i18n-wait body {
  visibility: hidden;
  animation: i18n-show 0s 1.5s forwards;
}

@keyframes i18n-show {
  to {
    visibility: visible;
  }
}

h1,
h2,
h3,
p {
  margin: 0;
}

a {
  color: inherit;
}

::selection {
  background: var(--accent);
  color: #fff;
}

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

[hidden] {
  display: none !important;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.wrap {
  width: min(100% - 2.5rem, 74rem);
  margin-inline: auto;
}

.icon {
  flex: none;
  width: 1.25em;
  height: 1.25em;
}

/* Brand: the mark and the name, top left of every page */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-decoration: none;
}

.brand svg {
  width: 1.75rem;
  height: 1.75rem;
}

/* The right end of a top bar: "My account", the theme switch, the language picker, then the page's own button */
.top-end {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* On a phone they close up, so the four fit on one line */
@media (max-width: 30rem) {
  .top-end {
    gap: 0.25rem;
  }
}

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 3rem;
  padding: 0 1.375rem;
  border: 1.5px solid transparent;
  border-radius: 999px;
  background: none; /* not the browser's own grey, which hides the text of a pill switch in dark mode */
  font: 600 1rem/1 var(--sans);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.15s, border-color 0.15s, color 0.15s, transform 0.15s var(--ease);
}

.btn-sm {
  min-height: 2.5rem;
  padding: 0 1.125rem;
  font-size: 0.9375rem;
}

/* Icon only, a 2.5rem circle. It needs an aria-label. */
.btn-icon {
  flex: none;
  width: 2.5rem;
  min-height: 2.5rem;
  padding: 0;
}

/* The theme switch holds a moon then a sun: the moon shows in light mode, the sun in dark mode */
:root:not([data-theme="dark"]) [data-theme-toggle] > :last-child,
:root[data-theme="dark"] [data-theme-toggle] > :first-child {
  display: none;
}

/* The language picker. In the HTML it is the browser's own <select>, laid unseen over a globe
   button: that is what shows when lang.js did not run. */
.lang {
  position: relative;
}

.lang select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  font-size: 1rem; /* iPhones zoom the page on a field with smaller text */
  cursor: pointer;
}

.lang:focus-within {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
}

/* lang.js turns it into this: a globe button, and a menu that opens under it */
.lang-menu {
  position: relative;
  display: inline-flex;
  flex: none;
}

/* The language code shows beside the globe where the top bars have the room, like "My account" */
.lang-menu > .btn span {
  display: none;
}

@media (min-width: 75rem) {
  .lang-menu > .btn {
    width: auto;
    padding: 0 0.875rem 0 0.75rem;
    gap: 0.375rem;
    font-size: 0.875rem;
    letter-spacing: 0.02em;
  }

  .lang-menu > .btn span {
    display: inline;
  }
}

.lang-menu > .btn[aria-expanded="true"] {
  border-color: var(--ink);
}

.lang-menu ul {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  z-index: 20;
  display: grid;
  gap: 0.125rem;
  min-width: 11rem;
  margin: 0;
  padding: 0.375rem;
  border: 1px solid var(--line);
  border-radius: var(--r-panel);
  background: var(--surface);
  box-shadow: var(--shadow);
  list-style: none;
  transform-origin: top right;
  animation: lang-open 0.18s var(--ease);
}

.lang-menu ul.to-right {
  right: auto;
  left: 0;
  transform-origin: top left;
}

@keyframes lang-open {
  from {
    opacity: 0;
    transform: translateY(-0.25rem) scale(0.97);
  }
}

.lang-menu li button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
  min-height: 2.75rem;
  padding: 0 0.875rem;
  border: 0;
  border-radius: 0.875rem;
  background: none;
  color: var(--ink);
  font: 500 0.9375rem/1 var(--sans);
  text-align: start;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.lang-menu li button:focus-visible {
  outline-offset: -2px;
}

/* The language the page is in: tinted, with a tick */
.lang-menu li [aria-current] {
  background: var(--tint);
  color: var(--accent-text);
  font-weight: 600;
}

.lang-menu li [aria-current]::after {
  content: "";
  width: 0.375rem;
  height: 0.6875rem;
  margin: 0 0.25rem 0.1875rem;
  border: solid currentColor;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

@media (hover: hover) {
  .lang-menu li button:not([aria-current]):hover {
    background: var(--bg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .lang-menu ul {
    animation: none;
  }
}

/* "My account" in a top bar: an icon button like the two switches beside it. From 75rem up,
   where every top bar has the room, its words show too. Its aria-label names it either way. */
.to-account span {
  display: none;
}

@media (min-width: 75rem) {
  .to-account {
    width: auto;
    padding: 0 1.125rem;
    font-size: 0.9375rem;
  }

  .to-account span {
    display: inline;
  }
}

/* The smallest phones have no room for a fourth button: this one goes */
@media (max-width: 22rem) {
  .to-account {
    display: none;
  }
}

.btn-primary {
  background: var(--accent);
  color: #fff;
}

.btn-ghost {
  border-color: var(--line);
  background: var(--surface);
  color: var(--ink);
}

@media (hover: hover) {
  .btn-primary:hover:not(:disabled) {
    background: var(--accent-hover);
  }

  .btn-ghost:hover:not(:disabled) {
    border-color: var(--ink);
  }
}

.btn:active:not(:disabled) {
  transform: scale(0.98);
}

.btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.text-link {
  color: var(--accent-text);
  font-weight: 600;
  text-decoration: none;
}

.text-link:hover {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* Form fields: label above, help or error below */
.label {
  display: block;
  margin-bottom: 0.375rem;
  font-size: 0.9375rem;
  font-weight: 600;
}

.label small {
  color: var(--muted);
  font-size: inherit;
  font-weight: 400;
}

.input {
  display: block;
  width: 100%;
  min-height: 3rem;
  padding: 0.625rem 0.875rem;
  border: 1.5px solid var(--line);
  border-radius: var(--r-input);
  background: var(--surface);
  color: var(--ink);
  font: 400 1rem/1.4 var(--sans);
  transition: border-color 0.15s;
}

.input::placeholder {
  color: var(--muted);
  opacity: 0.9; /* 4.8:1 on a light field; any fainter and the examples are hard to read */
}

.input:hover {
  border-color: color-mix(in srgb, var(--ink) 35%, var(--line));
}

.input:focus {
  border-color: var(--accent-text);
}

.input[aria-invalid="true"] {
  border-color: var(--danger);
}

.help,
.error {
  margin-top: 0.375rem;
  font-size: 0.875rem;
}

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

.error {
  color: var(--danger);
  font-weight: 600;
}

/* "Your card is not online yet": said once to someone who comes back to a card they left before
   publishing, under the top bar of the home page and at the top of the builder. One line, one
   button, and a cross that ends it. The amber ring is the mark of "not online yet" everywhere. */
.resume {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  align-items: center;
  gap: 0.5rem 0.75rem;
  padding: 0.625rem 0.625rem 0.625rem 1.125rem;
  border-radius: var(--r-panel);
  background: var(--surface);
  box-shadow: var(--shadow);
}

.resume p {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  min-width: 0;
  font-weight: 600;
}

.resume p::before {
  content: "";
  flex: none;
  width: 0.625rem;
  height: 0.625rem;
  border: 2px solid var(--warn);
  border-radius: 50%;
}

.resume .btn-icon {
  justify-self: end;
}

.resume.wrap {
  margin-top: 0.25rem;
}

/* On a phone the button goes under the sentence, as wide as the panel */
@media (max-width: 33rem) {
  .resume {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .resume p {
    grid-area: 1 / 1;
  }

  .resume .btn-icon {
    grid-area: 1 / 2;
  }

  .resume .btn-primary {
    grid-area: 2 / 1 / 3 / -1;
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
}

/* ---- The site's question and its notices (ask.js): never the browser's grey boxes ---- */
.ask-dialog {
  width: min(100% - 2rem, 27rem);
  max-width: none;
  padding: 0;
  border: 0;
  border-radius: var(--r-panel);
  background: var(--surface);
  color: var(--ink);
  box-shadow: 0 2px 6px rgb(13 15 21 / 0.08), 0 24px 64px rgb(13 15 21 / 0.28);
}

.ask-dialog[open] {
  animation: rise 0.25s var(--ease);
}

.ask-dialog::backdrop {
  background: rgb(13 15 21 / 0.5);
}

.ask-dialog-in {
  display: grid;
  gap: 0.625rem;
  padding: 1.5rem;
}

.ask-dialog h2 {
  font-size: 1.25rem;
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.ask-dialog p {
  color: var(--muted);
}

/* The way out first, the main button last: on a phone each takes the whole width, the main one on top */
.ask-dialog-buttons {
  display: flex;
  flex-wrap: wrap-reverse;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 0.875rem;
}

@media (max-width: 30rem) {
  .ask-dialog-buttons .btn {
    flex: 1 1 100%;
  }
}

/* What cannot be undone: filled in the colour of an error */
.ask-dialog .btn-danger {
  border-color: var(--danger);
  background: var(--danger);
  color: var(--surface);
}

.toasts {
  position: fixed;
  inset-inline: 1rem;
  bottom: calc(var(--toast-bottom, 1rem) + env(safe-area-inset-bottom));
  z-index: 60;
  display: grid;
  justify-items: center;
  gap: 0.5rem;
  pointer-events: none;
}

.toast {
  max-width: 26rem;
  padding: 0.875rem 1.125rem;
  border-radius: var(--r-input);
  background: var(--ink);
  color: var(--bg);
  box-shadow: var(--shadow);
  font-weight: 600;
  animation: rise 0.25s var(--ease);
}

.toast.is-error {
  border: 1.5px solid var(--danger);
  background: var(--surface);
  color: var(--ink);
}

/* On a wide screen: the corner, out of the way of the page's buttons */
@media (min-width: 48rem) {
  .toasts {
    inset-inline: auto 1.5rem;
    justify-items: end;
  }
}

/* ---- A thing to print, shown on screen (the business card): a real piece of paper ----
   Tilted a little in perspective, with a thin edge, a layered shadow and a light sheen that follows
   the pointer (account.js sets --sheen-x and --sheen-y). It lifts and straightens under the pointer,
   or while the focus is in its panel; on a touch screen a press tilts it. Only the picture on screen
   moves: what is downloaded and printed is the picture inside, untouched. */
.paper {
  position: relative;
  border-radius: 0.375rem;
  transform: perspective(60rem) rotateX(9deg) rotateY(-11deg) rotateZ(1.5deg);
  transform-origin: 50% 60%;
  box-shadow: 0 1px 0 #dfe1e6, 0 2px 0 #cdd0d7, 0 4px 3px rgb(13 15 21 / 0.08), 0 14px 20px -8px rgb(13 15 21 / 0.22), 0 30px 44px -16px rgb(13 15 21 / 0.28);
  transition: transform 0.5s var(--ease), box-shadow 0.5s var(--ease);
}

.paper > img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: inherit;
}

.paper::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(circle at var(--sheen-x, 25%) var(--sheen-y, 15%), rgb(255 255 255 / 0.5), rgb(255 255 255 / 0) 55%), linear-gradient(120deg, rgb(255 255 255 / 0) 35%, rgb(255 255 255 / 0.22) 50%, rgb(255 255 255 / 0) 65%);
  mix-blend-mode: soft-light;
  pointer-events: none;
}

:focus-within > .paper {
  transform: perspective(60rem) translateY(-0.375rem) rotateX(2deg) rotateY(-3deg);
  box-shadow: 0 1px 0 #dfe1e6, 0 2px 0 #cdd0d7, 0 6px 6px rgb(13 15 21 / 0.08), 0 24px 30px -10px rgb(13 15 21 / 0.24), 0 44px 60px -20px rgb(13 15 21 / 0.3);
}

@media (hover: hover) {
  .paper:hover {
    transform: perspective(60rem) translateY(-0.375rem) rotateX(2deg) rotateY(-3deg);
    box-shadow: 0 1px 0 #dfe1e6, 0 2px 0 #cdd0d7, 0 6px 6px rgb(13 15 21 / 0.08), 0 24px 30px -10px rgb(13 15 21 / 0.24), 0 44px 60px -20px rgb(13 15 21 / 0.3);
  }
}

@media (hover: none) {
  .paper:active {
    transform: perspective(60rem) rotateX(4deg) rotateY(-16deg) rotateZ(1deg);
  }
}

:root[data-theme="dark"] .paper {
  box-shadow: 0 1px 0 #b9bcc5, 0 2px 0 #8d919c, 0 4px 3px rgb(0 0 0 / 0.3), 0 14px 20px -8px rgb(0 0 0 / 0.5), 0 30px 44px -16px rgb(0 0 0 / 0.6);
}

/* No movement for someone who asked for less: the depth stays, flat and still */
@media (prefers-reduced-motion: reduce) {
  .paper,
  .paper:hover,
  .paper:active,
  :focus-within > .paper {
    transform: none;
    transition: none;
  }

  .ask-dialog[open],
  .toast {
    animation: none;
  }
}

/* The foot of every public page (its markup: src/foot.js). On a phone the brand, then the four
   columns two by two; from 48rem four columns; from 64rem the brand on the left of them. */
.site-foot {
  margin-top: 4rem;
  border-top: 1px solid var(--line);
  background: var(--surface);
  color: var(--muted);
  font-size: 0.9375rem;
}

.sf-in {
  display: grid;
  gap: 2.5rem;
  padding-block: 3rem 2rem;
}

.sf-brand {
  display: grid;
  gap: 1rem;
  align-content: start;
  justify-items: start;
  max-width: 21rem;
}

.sf-brand .brand {
  min-height: 2.5rem; /* room for a thumb */
  color: var(--ink);
  text-decoration: none;
}

.sf-brand p {
  margin: 0;
  text-wrap: balance;
}

/* English | Français: the language of the page is marked whichever address wrote it (a French page is written from the English file) */
.sf-lang {
  display: inline-flex;
  gap: 0.25rem;
  padding: 0.25rem;
  border: 1px solid var(--line);
  border-radius: 999px;
}

.sf-lang a {
  display: inline-flex;
  align-items: center;
  min-height: 2.5rem;
  padding-inline: 1rem;
  border-radius: 999px;
  color: var(--muted);
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
}

.sf-lang a:hover {
  color: var(--ink);
}

html[lang="en"] .sf-lang a[lang="en"],
html[lang="fr"] .sf-lang a[lang="fr"] {
  background: var(--tint);
  color: var(--accent-text);
}

.sf-cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2rem 1.5rem;
}

.sf-h {
  margin: 0 0 0.375rem;
  color: var(--ink);
  font-size: 0.875rem;
  font-weight: 700;
}

.sf-cols ul {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}

.sf-cols a {
  display: inline-flex;
  align-items: center;
  min-height: 2.5rem; /* room for a thumb */
  padding-block: 0.25rem; /* a name on two lines stays apart from the next */
  color: var(--muted);
  line-height: 1.35;
  text-decoration: none;
}

.sf-cols a:hover {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.sf-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem 2rem;
  padding-block: 1.5rem max(1.5rem, env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
  font-size: 0.8125rem;
}

.sf-bottom > p {
  margin: 0;
}

/* Privacy, Terms, Legal notice, Contact: beside the year */
.sf-legal {
  display: flex;
  flex-wrap: wrap;
  gap: 0 1.25rem;
  margin-right: auto;
}

.sf-legal a {
  display: inline-flex;
  align-items: center;
  min-height: 2.5rem; /* room for a thumb */
  color: var(--muted);
  text-decoration: none;
}

.sf-legal a:hover {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

@media (pointer: fine) {
  .sf-legal a {
    min-height: 1.75rem;
  }
}

@media (min-width: 48rem) {
  .sf-cols {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .sf-cols a {
    min-height: 2.125rem;
  }
}

/* With a mouse the switch is a small control, not the largest thing in the foot; a finger keeps its room */
@media (pointer: fine) {
  .sf-lang a {
    min-height: 2rem;
    padding-inline: 0.75rem;
    font-size: 0.8125rem;
  }
}

@media (min-width: 64rem) {
  .sf-in {
    grid-template-columns: minmax(0, 1fr) minmax(0, 2.6fr);
    gap: 4rem;
    padding-block: 4rem 3rem;
  }

  /* The headings share the line of the brand's name */
  .sf-h {
    margin-bottom: 0;
    line-height: 2.5rem;
  }
}

@media print {
  .site-foot {
    display: none;
  }
}
