/**
 * styles.css — page styles for the one-time note prototype.
 *
 * All colour, type and spacing come from tokens.css. The brand shows up as the
 * logo, Inter and the magenta CTA; there is no marketing hero, because this is
 * a tool someone opens to do one thing and leave.
 */

@import url('tokens.css');

/**
 * Inter, self-hosted.
 *
 * tokens.css names `Inter` at the head of --font-sans, copied from the
 * marketing site — but there it reads `var(--font-inter)`, a variable the Astro
 * Fonts API defines at build time. Copying the literal name across brought the
 * declaration without the face, so every page here has been falling through to
 * the system stack since the day the file was copied. This is the missing half.
 *
 * Served from our own origin rather than from a font provider. The provider
 * would not ship a font, it would ship a stylesheet from someone else's origin
 * onto the page that holds a decrypted credential — and it would hand that
 * origin the IP of every recipient who opens a note. The CSP says `font-src
 * 'self'` for the same reason.
 *
 * One variable file covers the four weights the page uses (400/500/600/700).
 * No italic face: nothing here is italic.
 *
 * The URL is relative on purpose, unlike the ones in index.html. A url() in CSS
 * resolves against the stylesheet, which is always /static/styles.css, so this
 * is correct at /n/:id too — the rule about absolute paths is about the HTML,
 * where the base is the document.
 *
 * Inter is licensed under the SIL Open Font License 1.1; the text ships beside
 * the file as inter-LICENSE.txt, which the licence requires.
 */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  /* The variable axis, not four static faces. */
  font-weight: 400 700;
  /* Text in the fallback face immediately, swapped when Inter lands. The
     alternative, `block`, hides text for up to three seconds — on a page whose
     job is to show somebody a credential once, invisible text is the worse
     failure. */
  font-display: swap;
  src: url('inter-latin-variable.woff2') format('woff2');
}

* { box-sizing: border-box; }

body {
  display: flex;
  flex-direction: column;
  margin: 0;
  min-height: 100vh;
  background: var(--surface);
  color: var(--on_surface);
  font-family: var(--font-sans);
  font-size: var(--body-md);
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
}

.glow {
  position: fixed;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 70% 50% at 50% 0%, rgba(139, 92, 246, .16) 0%, transparent 60%),
    radial-gradient(ellipse 40% 30% at 80% 40%, rgba(255, 110, 164, .10) 0%, transparent 70%);
}

/* Shares --measure with the footer so the logo up here and the one down there
   sit on the same vertical axis. Two different widths read as sloppiness. */
.page {
  position: relative;
  display: flex;
  flex: 1;
  flex-direction: column;
  justify-content: center;
  width: 100%;
  max-width: var(--measure);
  margin: 0 auto;
  padding: var(--space-8) var(--space-5);
}

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

/* ------------------------------------------------------------------ header */

.head { margin-bottom: var(--space-6); }

.site-logo {
  display: flex;
  width: max-content;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-6);
  color: var(--on_surface);
  text-decoration: none;
}

/* The mark ships as a black SVG using currentColor, and currentColor does not
   cross an <img> boundary — it rendered black on a black page. The site
   inverts it instead. */
.site-logo-mark {
  display: block;
  filter: invert(1);
}

.site-logo-text {
  font-size: 18px;
  font-weight: var(--fw-bold);
  letter-spacing: -0.02em;
}

.site-logo-sub {
  padding-left: var(--space-2);
  border-left: 1px solid var(--outline_variant);
  font-size: 14px;
  font-weight: var(--fw-medium);
  color: var(--on_surface_muted);
}

h1 {
  margin: 0 0 var(--space-2);
  font-size: var(--headline-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--track-headline);
  line-height: var(--leading-tight);
}

.lede {
  margin: 0;
  font-size: var(--body-md);
  color: var(--on_surface_variant);
}

/* -------------------------------------------------------------------- card */

.card {
  padding: var(--space-6);
  background: rgba(16, 19, 42, .65);
  border: 1px solid var(--outline_variant);
  border-radius: var(--radius-lg);
}

.card:focus { outline: none; }

/* !important, and it has to stay.
 *
 * This is a one-class selector competing with every other one-class selector
 * that sets `display`. `.btn` sets `inline-flex` and is declared further down
 * the file, so it won a tie on source order alone and `class="btn hidden"`
 * rendered in full — which is how the "send a note" button, hidden from
 * recipients on purpose, was shown to all of them anyway.
 *
 * Moving this rule to the end of the file would fix today and break the next
 * time somebody appends a component. A utility that means "not on the page"
 * cannot be a suggestion. */
.hidden { display: none !important; }

/* -------------------------------------------------------------------- tabs */

/* A segmented control rather than underlined tabs: two options, both equally
   ordinary, and neither is a section of a document you scroll between. */
.tabs {
  display: flex;
  gap: var(--space-2);
  padding: var(--space-2);
  margin-bottom: var(--space-6);
  background: var(--surface_container_lowest);
  border: 1px solid var(--outline_variant);
  border-radius: var(--radius-md);
}

.tab {
  flex: 1;
  padding: var(--space-2) var(--space-3);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font-family: var(--font-sans);
  font-size: var(--body-sm);
  font-weight: var(--fw-semibold);
  color: var(--on_surface_muted);
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}

.tab:hover { color: var(--on_surface_variant); }

.tab[aria-selected="true"] {
  background: var(--surface_container_high);
  color: var(--on_surface);
}

.tab:focus-visible {
  outline: 2px solid var(--primary_fixed);
  outline-offset: 2px;
}

/* ------------------------------------------------------------------ fields */

label {
  display: block;
  margin-bottom: var(--space-2);
  font-size: var(--label-md);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--on_surface_muted);
}

/* Marks a label's parenthetical as the aside it is, so "(opcional)" does not
   read with the same weight as the name of the field. */
.label-hint {
  font-weight: var(--fw-regular);
  text-transform: none;
  letter-spacing: normal;
}

/* A label with a control sitting next to it — the peek toggle beside
   "Contraseña". Baseline-aligned so the two do not look stacked by accident. */
.field-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
}

.field-head label { margin-bottom: var(--space-2); }

/* Text-weight buttons for actions that sit inside a field rather than under
   it. They must not compete with the magenta CTA for attention. */
.btn-ghost {
  padding: 0;
  background: none;
  border: none;
  border-radius: var(--radius-sm);
  font-family: var(--font-sans);
  font-size: var(--label-md);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--primary);
  cursor: pointer;
}

.btn-ghost:hover { color: var(--primary_fixed); }

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

textarea,
input[type="text"],
input[type="password"] {
  display: block;
  width: 100%;
  padding: var(--space-3) var(--space-4);
  background: var(--surface_container_lowest);
  color: var(--on_surface);
  border: 1px solid var(--outline_variant);
  border-radius: var(--radius-md);
  font-family: var(--font-mono);
  font-size: var(--body-md);
  line-height: var(--leading-normal);
}

textarea { resize: vertical; }

/* Space between one field and the label of the next, inside a panel that
   stacks several of them. */
input[type="text"] + label,
input[type="password"] + label,
textarea + label,
input[type="text"] + .field-head,
textarea + .field-head { margin-top: var(--space-5); }

textarea::placeholder,
input::placeholder { color: var(--on_surface_muted); }

textarea:focus,
input[type="text"]:focus,
input[type="password"]:focus {
  outline: none;
  border-color: var(--primary_fixed);
  box-shadow: 0 0 0 3px rgba(255, 110, 164, .14);
}

/* ------------------------------------------------------------------ expiry */

.ttl {
  padding: 0;
  margin: var(--space-6) 0 0;
  border: none;
}

.ttl legend {
  padding: 0;
  margin-bottom: var(--space-3);
  font-size: var(--label-md);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--on_surface_muted);
}

.ttl-options {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* Radios, kept as radios. The native input carries the grouping, the arrow-key
   behaviour and the announcement; only its appearance is replaced. */
.pill {
  display: inline-flex;
  margin-bottom: 0;
  border-radius: var(--radius-pill);
  text-transform: none;
  letter-spacing: normal;
  cursor: pointer;
}

.pill input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.pill span {
  display: block;
  padding: var(--space-2) var(--space-4);
  background: var(--surface_container_lowest);
  border: 1px solid var(--outline_variant);
  border-radius: var(--radius-pill);
  font-size: var(--body-sm);
  font-weight: var(--fw-medium);
  color: var(--on_surface_variant);
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.pill:hover span { border-color: var(--outline); color: var(--on_surface); }

.pill input:checked + span {
  background: var(--surface_container_high);
  border-color: var(--primary_fixed);
  color: var(--on_surface);
}

.pill input:focus-visible + span {
  outline: 2px solid var(--primary_fixed);
  outline-offset: 2px;
}

/* ----------------------------------------------------------------- buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  width: 100%;
  margin-top: var(--space-5);
  padding: var(--space-3) var(--space-6);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  font-size: var(--title-sm);
  font-weight: var(--fw-semibold);
  /* Several buttons here are anchors — signing in and starting a new note are
     navigations, not actions. Without this they arrive underlined and read as
     links wearing a button, which is the one thing a button must not look like. */
  text-decoration: none;
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.btn:focus-visible {
  outline: 2px solid var(--primary_fixed);
  outline-offset: 2px;
}

.btn[disabled] { opacity: .6; cursor: default; }

/* Solid magenta, matching the site's CTA. Reserved for the safe primary action
   — never for anything destructive. */
.btn--primary {
  background: var(--primary_container);
  color: var(--on_primary_container);
}

.btn--primary:hover:not([disabled]) { background: var(--primary_fixed_dim); }

.btn--secondary {
  background: transparent;
  border-color: var(--outline_variant);
  color: var(--on_surface_variant);
}

.btn--secondary:hover { border-color: var(--outline); color: var(--on_surface); }

/* ------------------------------------------------------------------ output */

.link-box {
  padding: var(--space-4);
  background: var(--surface_container_lowest);
  border: 1px solid var(--outline_variant);
  border-radius: var(--radius-md);
  font-family: var(--font-mono);
  font-size: var(--body-sm);
  color: var(--primary);
  word-break: break-all;
}

.secret {
  margin: var(--space-4) 0;
  padding: var(--space-5);
  background: var(--surface_container_lowest);
  border: 1px solid var(--primary_fixed);
  border-radius: var(--radius-md);
  font-family: var(--font-mono);
  font-size: var(--body-lg);
  color: var(--on_surface);
  white-space: pre-wrap;
  word-break: break-word;
}

/* ---------------------------------------------------- revealed note fields */

.field + .field { margin-top: var(--space-5); }

.field-label {
  font-size: var(--label-md);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--on_surface_muted);
}

.field-actions {
  display: flex;
  gap: var(--space-4);
}

.field-value { margin: var(--space-2) 0 0; }

/* Everything that is not the secret itself. Keeps the magenta frame meaning
   one thing, so the eye lands on the password and not on the reminder next to
   it. Free-text notes get it too — there the whole note is the secret. */
.field-value--plain { border-color: var(--outline_variant); }

/* Bullets, spaced out so a long mask does not read as one solid bar — and
   never wrapped, because a mask has no meaningful line breaks. */
.field-value--masked {
  letter-spacing: 0.2em;
  color: var(--on_surface_muted);
  white-space: nowrap;
  overflow: hidden;
}

/* ------------------------------------------------------------ status notes */

.note {
  padding: var(--space-4);
  margin-bottom: var(--space-5);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font-size: var(--body-md);
  line-height: var(--leading-normal);
}

.note--ok {
  background: rgba(74, 222, 128, .1);
  border-color: rgba(74, 222, 128, .28);
  color: var(--success);
}

.note--warn {
  background: rgba(251, 191, 36, .1);
  border-color: rgba(251, 191, 36, .28);
  color: var(--warning);
}

.note--error {
  background: rgba(248, 113, 113, .1);
  border-color: rgba(248, 113, 113, .28);
  color: var(--error);
}

/* An error surfacing under the button reads better below it than above. */
#create-error { margin: var(--space-5) 0 0; }

.fineprint {
  margin: var(--space-4) 0 0;
  font-size: var(--body-sm);
  color: var(--on_surface_muted);
}

/* The two plain links inside a card — signing out, and signing back in after a
   session expires. Without this they arrive as the browser's default blue,
   underlined, on a near-black page: unreadable, and visibly not ours.
   Buttons are excluded; several of them are anchors and already styled. */
.card a:not(.btn) {
  color: var(--primary);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color .15s ease, color .15s ease;
}

.card a:not(.btn):hover {
  color: var(--primary_fixed);
  border-bottom-color: currentColor;
}

.card a:not(.btn):focus-visible {
  outline: 2px solid var(--primary_fixed);
  outline-offset: 3px;
  border-radius: 2px;
}
