/* ==========================================================================
   THE DOOR OF THE CLIENT AREA

   Carlos: «lo que si quiero conservar es el estilo de loging lo del pin etc que
   hay para los otros acceder asi mola». So this is the same door the panel has:
   the photograph behind, the glass card, the two keys picked by two radios and
   the PIN drawn as six boxes. What changed is the brand around it: Inter
   instead of the panel's type, and the navy and azure of the tokens instead of
   the old blues.

   IT LOADS AFTER site.css AND LEANS ON IT for the fonts and the tokens
   (--color-*, --font-sans, --radius-*). site.css also carries global rules for
   .btn, .field, .alert and friends that were written for the public pages, so
   everything here is scoped under .gate: the door never inherits a form layout
   meant for the contact page, and the contact page never inherits the door.

   The one exception to Inter is the no-JavaScript PIN field further down, and
   the reason is written there.
   ========================================================================== */

/* ----------------------------------------------------- door palette --
   Local to the door and not on :root, so none of these names can collide with
   the public site. The glass values are the panel's, which were tuned against
   this same photograph; the veil and the flat wash are moved to navy. */

.gate {
  --gate-ink:          var(--color-on-dark);
  --gate-ink-2:        var(--color-on-dark-2);
  --gate-veil-1:       rgba(16, 20, 30, .86);     /* --color-night */
  --gate-veil-2:       rgba(25, 31, 47, .72);     /* --color-navy */
  --gate-veil-3:       rgba(37, 46, 70, .44);    /* --color-azure-deep */
  --gate-wash:         rgba(25, 31, 47, .40);
  --gate-shadow-text:  0 2px 16px rgba(9, 11, 17, .55);
  --gate-halo:         drop-shadow(0 3px 16px rgba(9, 11, 17, .45));
  --glass:             rgba(11, 14, 21, .06);
  --glass-solid:       rgba(16, 20, 30, .82);
  --glass-line:        rgba(255, 255, 255, .42);
  --glass-shine:       rgba(255, 255, 255, .30);
  --glass-shadow:      0 12px 28px -14px rgba(7, 9, 13, .50);
  --glass-field:       rgba(255, 255, 255, .14);
  --glass-field-line:  rgba(255, 255, 255, .34);
  --glass-field-ph:    rgba(255, 255, 255, .55);
  --glass-ring:        rgba(182, 191, 215, .30);  /* --color-focus-on-dark, softened */
  --glass-down:        #F09A93;
  --glass-down-halo:   rgba(240, 154, 147, .24);
  --glass-up:          #5FCB9A;
  --glass-up-halo:     rgba(95, 203, 154, .24);
  /* The inlined thumbnail that stands in while the photograph comes down. It
     travels as a data: URI, which the site policy allows under img-src. */
  --gate-photo-mini: url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABQODxIPDRQSEBIXFRQYHjIhHhwcHj0sLiQySUBMS0dARkVQWnNiUFVtVkVGZIhlbXd7gYKBTmCNl4x9lnN+gXz/2wBDARUXFx4aHjshITt8U0ZTfHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHz/wAARCAAOABgDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwC/DlBDmPeWU5yPl65p/kx/M2RtGeAf61RSZ7eMh2LIf4PSny3AMKnadhfaRnFbKTgcr5aj0KF0qli7Ej0A70U2SRYZGWJ5N2OS1FTvqapW0P/Z");
}

/* The body under the door is night and not the white paper of the public
   site: during the instant before the photograph paints, and in the strip the
   browser shows when a phone overscrolls, white would flash. */
.gate-page { background: var(--color-night); }

/* THE hidden ATTRIBUTE MUST WIN OVER ANY display WRITTEN HERE. The UA rule for
   [hidden] weighs as a type selector, so .btn's inline-flex or the eye's flex
   would beat it and leave on screen the submit button gate.js hides in PIN mode
   and the eye it has not switched on yet. site.css does not carry this rule
   globally, so the door carries its own. */
.gate [hidden] { display: none !important; }

/* Inline icons. Stroke only, painted in currentColor, so each icon takes the
   colour of whatever holds it and there is no second place to theme. They are
   inline-block against the display:block site.css gives every svg, which would
   otherwise drop the alert icon onto a line of its own. */
.gate .ico {
  display: inline-block;
  flex: none;
  width: 1.15em;
  height: 1.15em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -.2em;
}

/* ------------------------------------------------------------ layout -- */

.gate {
  /* dvh and not vh. With vh the 100% measures the screen WITH the browser bar
     retracted, so the door spills below the bar and the button has to be
     scrolled to. dvh measures what is on show, and it shrinks when the keyboard
     comes up, which is what keeps the sign in button reachable. */
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  grid-template-columns: 1fr 1fr;
  position: relative;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.5;
  color: var(--gate-ink);
}

.gate__art {
  position: relative;
  z-index: 1;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px;
}

.gate__mark { position: relative; z-index: 1; text-align: center; color: var(--gate-ink); }
/* The mark is taller than it is wide (288x312): at 132 wide it takes 143 of
   height, which is what the panel asks for without eating the name. */
.gate__mark img {
  width: 132px;
  height: auto;
  display: block;
  margin: 0 auto 26px;
  filter: var(--gate-halo);
}
.gate__mark h1 {
  font-family: var(--font-sans);
  font-size: 44px;
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-display);
  line-height: 1.05;
  margin: 0 0 10px;
  color: var(--gate-ink);
  text-shadow: var(--gate-shadow-text);
}
.gate__mark p {
  max-width: 34ch;
  margin: 0 auto;
  color: var(--gate-ink-2);
  font-size: 15px;
  font-weight: var(--weight-medium);
  letter-spacing: .01em;
  text-shadow: var(--gate-shadow-text);
}

.gate__form {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
}

/* --------------------------------------------------------- the photo --
   Three layers, each in its place so one can move without the others: the
   photo in the background of .gate, the veil in its ::after, and the mark and
   the card above both with a z-index. */

.gate--photo {
  background-color: var(--color-mist);
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
  /* The fallback first: a plain jpg for the browser without image-set(), over
     the inlined thumbnail. */
  background-image: url("../img/login-bg.jpg"), var(--gate-photo-mini);
}

/* The good one goes inside @supports and not as a second declaration, because
   the thumbnail travels in a var(): a declaration holding a var() is voided at
   computed-value time instead of being dropped at parse time, so where
   image-set() does not exist it would not fall back to the rule above and the
   door would end up with only the flat colour. */
@supports (background-image: image-set(url("../img/login-bg.webp") type("image/webp"))) {
  .gate--photo {
    background-image:
      image-set(url("../img/login-bg.webp") type("image/webp"),
                url("../img/login-bg.jpg")  type("image/jpeg")),
      var(--gate-photo-mini);
  }
}

/* The veil covers the whole door and sits under everything that is read. The
   photograph is a bright daylight scene, so without it white text on the sky
   is illegible; navy toward the top left where the mark sits, looser toward
   the bottom right so the picture still reads. */
.gate--photo::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: linear-gradient(155deg,
    var(--gate-veil-1) 0%,
    var(--gate-veil-2) 56%,
    var(--gate-veil-3) 100%);
}

/* A flat navy block over the left half. Flat and not a gradient on purpose:
   what is wanted is a clean line down the middle, and a gradient gives none. */
.gate--photo .gate__art::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: var(--gate-wash);
}

/* ------------------------------------------------------- back button --
   Glass like the card, because it sits over the same photograph. */

.gate .gate__back {
  position: absolute;
  z-index: 2;
  top: calc(18px + env(safe-area-inset-top, 0px));
  right: calc(18px + env(safe-area-inset-right, 0px));
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 9px 15px 9px 12px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--glass-line);
  background: var(--glass);
  box-shadow: var(--glass-shadow);
  backdrop-filter: blur(6px) saturate(135%);
  -webkit-backdrop-filter: blur(6px) saturate(135%);
  color: var(--gate-ink);
  text-decoration: none;
  font-size: 13px;
  font-weight: var(--weight-medium);
  transition: background-color .18s ease, border-color .18s ease;
}
.gate .gate__back svg {
  display: block;
  width: 15px; height: 15px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
.gate .gate__back:hover {
  color: var(--gate-ink);
  background: rgba(255, 255, 255, .16);
  border-color: rgba(255, 255, 255, .6);
}
.gate :focus-visible { outline-color: var(--color-focus-on-dark); }

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

.gate__box {
  position: relative;
  width: min(408px, 100%);
  padding: 34px;
  border-radius: var(--radius-xl);
  border: 1px solid rgba(255, 255, 255, .16);
  background: var(--glass);
  box-shadow: var(--glass-shadow);
  backdrop-filter: blur(6px) saturate(135%);
  -webkit-backdrop-filter: blur(6px) saturate(135%);
}

/* Where there is no backdrop-filter the card would stay translucent and
   unblurred, the form read over whatever passes underneath. There it goes
   nearly opaque. Both forms are asked for because Safari only has the
   prefixed one. */
@supports not ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  .gate__box { background: var(--glass-solid); }
}

.gate__box h2 {
  font-family: var(--font-sans);
  font-size: 22px;
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-heading);
  line-height: 1.2;
  margin: 0 0 6px;
  color: var(--gate-ink);
}
.gate__box > p { color: var(--gate-ink-2); font-size: 15px; margin: 0 0 24px; }
.gate .muted { color: var(--gate-ink-2); }
.gate .gate__small { font-size: 12.5px; margin: 20px 0 0; line-height: 1.5; }
.gate .gate__small + .gate__small { margin-top: 10px; }

/* ------------------------------------------------------- the fields --
   site.css makes .field a flex column meant for the contact form; the door
   wants its own stacked block with the panel's spacing. */

.gate .field { display: block; margin: 0 0 16px; }
.gate .field label {
  display: block;
  margin-bottom: 6px;
  font-size: 13px;
  font-weight: var(--weight-medium);
  color: var(--gate-ink);
}
.gate .field .hint { font-size: 12.5px; color: var(--gate-ink-2); margin-top: 6px; }

/* THE DOOR FIELDS ARE 16 px, and that is not taste. Under 16, iOS zooms the
   page in by itself the moment the box takes focus and leaves it zoomed, with
   the card wider than the screen. The vertical padding carries the box past the
   44 px of height the eye button needs. The fields are glass too: an opaque
   white one in here breaks the card. */
.gate input[type=text],
.gate input[type=password] {
  width: 100%;
  min-height: 48px;
  padding: 11px 14px;
  border: 1px solid var(--glass-field-line);
  border-radius: var(--radius-md);
  background: var(--glass-field);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.4;
  color: var(--gate-ink);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.gate input::placeholder { color: var(--glass-field-ph); }
.gate input:focus {
  outline: none;
  border-color: var(--gate-ink);
  box-shadow: 0 0 0 3px var(--glass-ring);
}

/* Chrome autofill paints its own background inside the field and wrecks the
   glass the moment a saved password is pulled in. No property turns it off:
   it is covered with a huge inset shadow and the ink is forced. */
.gate input:-webkit-autofill,
.gate input:-webkit-autofill:hover,
.gate input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--gate-ink);
  -webkit-box-shadow: 0 0 0 1000px rgba(20, 25, 38, .92) inset;
  caret-color: var(--gate-ink);
  transition: background-color 9999s ease-in-out 0s;
}

/* ------------------------------------------------ the secret fields --
   The box with an eye, drawn by secret_field() in lib/core.php and switched on
   by assets/js/gate.js. THE GAP ON THE RIGHT HANGS OFF .secret--eye AND NOT OFF
   .secret: that class is put on by the script, so a browser that never ran it
   keeps a plain field with no hole reserved for a button that is not there. */

.gate .secret { position: relative; display: block; }
.gate .secret.secret--eye input { padding-right: 48px; }

.gate .secret__eye {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  /* 44 px is the smallest target a finger hits without aiming. */
  width: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  margin: 0;
  border: 0;
  background: none;
  border-radius: var(--radius-md);
  color: var(--gate-ink-2);
  cursor: pointer;
}
.gate .secret__eye:hover { color: var(--gate-ink); }
.gate .secret__eye .ico { width: 20px; height: 20px; vertical-align: 0; }
/* One drawing for both states: the slash across the eye is a path of its own,
   shown when paintEye() in gate.js marks the icon as slashed, in the same call
   that sets aria-pressed, so the picture cannot disagree with what the button
   announces. */
.gate .secret__eye .ico__slash { display: none; }
.gate .secret__eye .ico--slashed .ico__slash { display: inline; }

/* SIX CELLS, ONE FIELD, WITHOUT JAVASCRIPT. The field is drawn as six cells by
   a gradient under it and the characters are spaced one per cell. That spacing
   is arithmetic on 1ch, and 1ch is only the width of every character in a
   monospace face: Inter's dots are not the width of its zero. So this one field
   uses the system monospace, which downloads nothing and costs no policy. With
   the script running this field goes transparent over the six boxes below and
   its face is never seen. */
.gate .secret--pin { display: flex; align-items: stretch; gap: 4px; }

.gate .secret--pin input.pin {
  --pin-cell: 44px;
  width: calc(var(--pin-cell) * 6);
  max-width: 100%;
  padding: 11px 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 19px;
  letter-spacing: calc(var(--pin-cell) - 1ch);
  text-indent: calc((var(--pin-cell) - 1ch) / 2);
  background-image: repeating-linear-gradient(90deg,
      transparent 0 calc(var(--pin-cell) - 1px),
      var(--glass-line) calc(var(--pin-cell) - 1px) var(--pin-cell));
  background-repeat: no-repeat;
  /* The last divider would sit on the right border and double it. */
  background-size: calc(var(--pin-cell) * 5 + 1px) 100%;
}

@media (max-width: 380px) {
  .gate .secret--pin input.pin { --pin-cell: 38px; font-size: 17px; }
}

/* ------------------------------------- six boxes and one cursor --
   The PIN as Carlos asked for it: six boxes, ONE cursor that slides between
   them, a red ring and a single shake when the key is wrong, a green ring box
   by box when it opens. It is still the one field above: gate.js adds .otp to
   the wrapper, unhides the six spans and mirrors the digits into them, and the
   real field goes ON TOP, transparent, keeping the focus, the paste, the
   password manager and the screen reader. Everything here hangs off .otp. */

.gate .secret__otp { position: relative; display: flex; min-width: 0; }
.gate .otp { flex: 1 1 auto; }

.gate .secret--pin .otp input.pin {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  max-width: none;
  height: 100%;
  min-height: 0;
  margin: 0;
  padding: 0;
  text-indent: 0;
  letter-spacing: 0;
  color: transparent;
  -webkit-text-fill-color: transparent;
  caret-color: transparent;
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  outline: none;
}
.gate .secret--pin .otp input.pin:focus { border-color: transparent; box-shadow: none; }
.gate .secret--pin .otp input.pin::selection { background: transparent; color: transparent; }
.gate .gate__box .otp input.pin:-webkit-autofill,
.gate .gate__box .otp input.pin:-webkit-autofill:hover,
.gate .gate__box .otp input.pin:-webkit-autofill:focus {
  -webkit-box-shadow: none;
  -webkit-text-fill-color: transparent;
  caret-color: transparent;
}

.gate .otp .otp__cells {
  position: relative;
  display: flex;
  gap: 8px;
  width: 100%;
}

/* 50 px is a ceiling and not a fixed width: the boxes flex down together on a
   narrow card and stay square-ish, around 44 px on a 390 px phone. */
.gate .otp__cell {
  flex: 1 1 0;
  min-width: 0;
  max-width: 50px;
  height: 52px;
  display: grid;
  place-items: center;
  border: 1px solid var(--glass-field-line);
  border-radius: var(--radius-sm);
  background: var(--glass-field);
  font-family: var(--font-sans);
  font-variant-numeric: tabular-nums;
  /* Large because what a box ever shows is a dot, and Inter's bullet at text
     size is a speck. */
  font-size: 28px;
  font-weight: var(--weight-semibold);
  line-height: 1;
  color: var(--gate-ink);
  transition: border-color .15s ease, box-shadow .15s ease, background .15s ease,
              color .15s ease;
}

/* The focus ring lands on the box the cursor is in, and only while the real
   field has the focus. A keyboard selection shows as a wash on the boxes it
   covers, because the field's own selection is invisible. */
.gate .otp:focus-within .otp__cell--active { border-color: var(--gate-ink); box-shadow: 0 0 0 3px var(--glass-ring); }
.gate .otp .otp__cell--selected { background: var(--glass-shine); }

/* THE ONE CURSOR. A bar that lives in the row and is moved with a transform,
   which is what makes it slide instead of blinking out here and in there.
   gate.js writes the position into --otp-x through the CSSOM. */
.gate .otp__caret {
  position: absolute;
  top: 13px;
  bottom: 13px;
  left: 0;
  width: 2px;
  margin-left: -1px;
  border-radius: 1px;
  background: var(--gate-ink);
  opacity: 0;
  pointer-events: none;
  transform: translateX(var(--otp-x, 0px));
  transition: transform .16s cubic-bezier(.2, .8, .2, 1);
}
.gate .otp:focus-within .otp__caret { opacity: 1; animation: otp-blink 1.1s step-end infinite; }
@keyframes otp-blink { 50% { opacity: 0; } }

/* WRONG: every box red and the row shakes ONCE; gate.js takes the class off at
   the next keystroke, which lets a second failure shake again. The light reds
   and greens are used because the brand's --color-error and --color-success
   are made for white paper and sink into the veil. */
.gate .otp.otp--error .otp__cell { border-color: var(--glass-down); box-shadow: 0 0 0 3px var(--glass-down-halo); }
.gate .otp.otp--error .otp__cells { animation: otp-shake .42s cubic-bezier(.36, .07, .19, .97) both; }
@keyframes otp-shake {
  10%, 90%      { transform: translateX(-1px); }
  20%, 80%      { transform: translateX(2px); }
  30%, 50%, 70% { transform: translateX(-4px); }
  40%, 60%      { transform: translateX(4px); }
}

/* RIGHT: green box by box from the left, fill and digit riding the same delay
   as the edge. Carlos: «cuando la contraseña es correcta que también se vuelva
   verde el interior progresivamente, cada número a la vez que la animación del
   borde verde». gate.js waits for the last one before navigating. */
.gate .otp.otp--ok .otp__cell {
  border-color: var(--glass-up);
  box-shadow: 0 0 0 3px var(--glass-up-halo);
  background: var(--glass-up-halo);
  color: var(--glass-up);
}
.gate .otp.otp--ok .otp__cell:nth-child(2) { transition-delay: 60ms; }
.gate .otp.otp--ok .otp__cell:nth-child(3) { transition-delay: 120ms; }
.gate .otp.otp--ok .otp__cell:nth-child(4) { transition-delay: 180ms; }
.gate .otp.otp--ok .otp__cell:nth-child(5) { transition-delay: 240ms; }
.gate .otp.otp--ok .otp__cell:nth-child(6) { transition-delay: 300ms; }

@media (max-width: 380px) {
  .gate .otp .otp__cells { gap: 6px; }
  .gate .otp__cell { height: 46px; font-size: 24px; }
}

/* ------------------------------------------------------- the notice --
   The box is always in the page because it is an aria-live region; gate.js
   drops the alert in and fades it after six seconds. site.css has an .alert
   meant for the contact form grid; this one is the door's. */

.gate .alert {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin: 0 0 18px;
  padding: 11px 14px;
  border-radius: var(--radius-md);
  font-size: 14px;
  line-height: 1.45;
  transition: opacity .25s ease;
}
.gate .alert .ico { margin-top: 1px; }
.gate .alert--error {
  border: 1px solid rgba(240, 154, 147, .55);
  background: rgba(120, 20, 16, .42);
  color: #FFFFFF;
}
.gate .alert--error .ico { color: var(--glass-down); }
.gate .alert--gone { opacity: 0; }

/* ------------------------------------------- the two keys, one at a time --
   No JavaScript in this. Two real radios sharing a name sit loose in the form,
   before the control that is seen and before the fields, and the sibling
   combinator over :checked shows one key and hides the other. The choice
   travels in the submission, which is what lets index.php check the key of the
   declared mode. Each selector names the value and not the id. */

/* Clipped and not display:none: a clipped radio still takes focus and answers
   the arrow keys, and a clipped name is still read out for a label that shows
   only an icon. */
.gate .gate__pick,
.gate .gate__mode-name {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.gate .gate__modes {
  display: flex;
  justify-content: center;
  gap: 16px;
  margin: 4px 0 20px;
}

/* 52 px across clears the 44 px a thumb hits without aiming. The border is
   2 px in BOTH states and only changes colour, so picking one does not nudge
   its neighbour. */
.gate .gate__mode {
  position: relative;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border: 2px solid var(--glass-field-line);
  border-radius: 50%;
  background: transparent;
  color: var(--gate-ink-2);
  line-height: 1;
  cursor: pointer;
  user-select: none;
  transition: background .15s ease, color .15s ease, border-color .15s ease,
              transform .15s ease;
}
.gate .gate__mode .ico { width: 22px; height: 22px; vertical-align: 0; }
.gate .gate__mode:hover { color: var(--gate-ink); border-color: var(--glass-line); }

/* The chosen one is not told apart by colour alone: it is filled, its edge
   goes full strength and it is bigger, and fill and size both survive a grey
   screenshot. */
.gate .gate__pick[value="pin"]:checked      ~ .gate__modes .gate__mode--pin,
.gate .gate__pick[value="password"]:checked ~ .gate__modes .gate__mode--password {
  background: var(--glass-shine);
  border-color: var(--gate-ink);
  color: var(--gate-ink);
  transform: scale(1.08);
}

/* The keyboard ring lands on the label, because the radio is one pixel across.
   An outline, which follows border-radius and clears the 8 % the chosen circle
   grows by. */
.gate .gate__pick[value="pin"]:focus-visible      ~ .gate__modes .gate__mode--pin,
.gate .gate__pick[value="password"]:focus-visible ~ .gate__modes .gate__mode--password {
  outline: 2px solid var(--color-focus-on-dark);
  outline-offset: 3px;
}

/* Only the box of the checked mode is drawn. The other stays in the DOM, and
   gate.js disables it so it is not even sent. */
.gate .gate__key { display: none; }
.gate .gate__pick[value="pin"]:checked      ~ .gate__key--pin,
.gate .gate__pick[value="password"]:checked ~ .gate__key--password { display: block; }

/* ---------------------------------------------------------- buttons --
   site.css has no primary button; .btn there is the public site's shape. The
   door's sign in button is the azure of the brand: navy would sink into the
   navy veil it sits on. */

.gate .btn--primary {
  min-height: 48px;
  margin-top: 4px;
  border: 0;
  border-radius: var(--radius-md);
  background: var(--color-azure);
  color: var(--color-on-dark);
  font-size: 15px;
  font-weight: var(--weight-semibold);
}
.gate .btn--primary:hover { background: var(--color-azure-deep); color: var(--color-on-dark); }
.gate .btn--block { display: flex; width: 100%; justify-content: center; }
.gate .btn[disabled] { opacity: .55; }

/* The language switch: a plain link at the foot of the card, quiet until it is
   pointed at. 44 px of height although the text is small, because the tap area
   is the link and not the words. */
.gate .gate__lang {
  display: flex;
  align-items: center;
  justify-content: center;
  width: fit-content;
  min-height: 44px;
  margin: 12px auto 0;
  padding: 6px 16px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  color: var(--gate-ink-2);
  font-size: 13px;
  font-weight: var(--weight-medium);
  text-decoration: none;
  transition: background .14s ease, color .14s ease, border-color .14s ease;
}
.gate .gate__lang:hover {
  background: var(--glass-field);
  border-color: var(--glass-field-line);
  color: var(--gate-ink);
}

/* ----------------------------------------------------------- narrow --
   ONE COLUMN AND ANOTHER IDEA, not the two halves squeezed: the mark and the
   name on one line at the top, and the card below over the same photo. The
   safe areas are added by hand because the page asks for viewport-fit=cover. */

@media (max-width: 860px) {
  .gate--photo {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
  }

  /* The flat wash goes: in one column it would eat the whole band the mark sits
     on. The veil turns vertical, dense at the top where the mark falls. */
  .gate--photo .gate__art::before { content: none; }
  .gate--photo::after {
    background: linear-gradient(180deg,
      var(--gate-veil-1) 0%,
      var(--gate-veil-2) 46%,
      var(--gate-veil-3) 100%);
  }

  .gate__art {
    padding: calc(24px + env(safe-area-inset-top, 0px))
             calc(64px + env(safe-area-inset-right, 0px))
             18px
             calc(64px + env(safe-area-inset-left, 0px));
  }
  .gate__mark {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 4px 12px;
  }
  .gate__mark img { width: 40px; margin: 0; flex: 0 0 auto; }
  .gate__mark h1 { font-size: 30px; margin: 0; }
  .gate__mark p { flex: 1 0 100%; max-width: none; margin: 0; font-size: 14px; }

  /* Pinned to the top and not centred: centred, the card is pushed up when
     the keyboard shrinks what is visible and the button ends above the edge.
     Pinned, the 1fr row grows instead of clipping and the page scrolls. */
  .gate__form {
    align-items: flex-start;
    padding: 0
             calc(16px + env(safe-area-inset-right, 0px))
             calc(24px + env(safe-area-inset-bottom, 0px))
             calc(16px + env(safe-area-inset-left, 0px));
  }
  .gate__box { width: 100%; padding: 24px 18px; }

  /* Only the arrow on a phone: the word next to the mark pushes the name. */
  .gate .gate__back { padding: 9px; }
  .gate .gate__back span {
    position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%);
  }
}

/* No sliding, no shaking, no blinking and no stagger for whoever asked the
   system for less motion. Spelled out because an infinite blink at 0 ms is a
   flicker, not a still cursor. */
@media (prefers-reduced-motion: reduce) {
  .gate .otp__caret { transition: none; animation: none !important; }
  .gate .otp.otp--error .otp__cells { animation: none; }
  .gate .otp.otp--ok .otp__cell:nth-child(n) { transition-delay: 0s; }
  .gate .gate__mode { transition: none; }
}
