/*
 * Buffet -- the front door: the installation's identity and the sign-in form, one document.
 *
 * Its own stylesheet rather than a section of app.css because this page is what somebody sees when
 * they have no standing in the application at all, so it shares the design tokens and none of the
 * shell. app.css is loaded first and defines every custom property used here; nothing below
 * re-declares a colour.
 *
 * **The three `front-` rules at the bottom arrived at D259, and they replaced something worse.** The
 * front page was a separate document with its own INLINE stylesheet carrying a second, duplicate
 * colour palette -- a light and a dark set of six hex values that no rule kept in step with these.
 * Folding the two documents let that palette go entirely: the identity block is styled here now, in
 * the same tokens as everything around it. It also let the page keep a CSP of `style-src 'self'`
 * with no `'unsafe-inline'`, which an inline block would have forced.
 *
 * The SMS block is styled deliberately unlike the rest -- separated by a rule -- because it is an
 * alternative to the form above it rather than a continuation of it.
 *
 * The roster's styles were here until D248 and went with the roster. What replaced them is the
 * honeypot's off-canvas rule at the bottom, which is the only thing in this file whose exact
 * declarations matter to behaviour rather than to appearance -- see the comment above it.
 */

.signin-body
{
	background: var( --page-background );
	color: var( --ink );
	min-height: 100vh;
	margin: 0;
	display: flex;
	justify-content: center;
	align-items: flex-start;
}

.signin-main
{
	width: min( 42rem, 100% );
	padding: 3rem 1.5rem 5rem;
	display: flex;
	flex-direction: column;
	gap: 1.5rem;
}

.signin-logo
{
	width: 8.5rem;
	height: auto;
	align-self: center;
}

/* The same two-file, CSS-swapped logo the shell uses: a logo that needs script to be the right
   colour is a logo that flashes the wrong one first. */
.signin-logo-dark { display: none; }

@media ( prefers-color-scheme: dark )
{
	.signin-logo-light { display: none; }
	.signin-logo-dark { display: block; }
}

.signin-main h1
{
	font-size: var( --text-xl );
	margin: 0 0 .35rem;
}

.signin-main h2
{
	font-size: var( --text-lg );
	margin: 0 0 .35rem;
}

.signin-main p
{
	margin: 0 0 .75rem;
	color: var( --ink-quiet );
	line-height: 1.5;
}

.signin-request,
.signin-confirm,
.signin-already,
.signin-closed
{
	background: var( --card-background );
	border: 1px solid var( --rule );
	border-radius: .5rem;
	padding: 1.5rem;
	box-shadow: var( --shadow-card );
}

.signin-notice
{
	padding: .75rem 1rem;
	border-radius: .4rem;
	margin: 0;
	line-height: 1.45;
}

.signin-notice-accent { background: var( --accent-quiet ); color: var( --ink ); }
.signin-notice-warn { background: var( --warning-quiet ); color: var( --warning ); }
.signin-notice-plain { background: var( --card-background ); border: 1px solid var( --rule ); }

.signin-email-form
{
	display: flex;
	flex-direction: column;
	gap: .4rem;
	align-items: flex-start;
}

.signin-email-form label
{
	font-size: var( --text-base );
	color: var( --ink-quiet );
}

.signin-email-form input[ type="email" ]
{
	width: 100%;
	max-width: 22rem;
	/* Vertical padding from the system height rather than from this file: `.5rem` made this field
	   39.0px beside a 37.4px button, which is the kind of difference nobody can name and everybody
	   can see. app.css's --control-height sets the floor; this only has to not exceed it. */
	padding: .3rem .6rem;
	border: 1px solid var( --rule );
	border-radius: .35rem;
	background: var( --page-background );
	color: var( --ink );
	font: inherit;
}

/* ROUND, like every other pressable thing in this interface (Jon, 2026-09-04). These were .35rem
   rectangles -- the sign-in page is the one surface a person meets before the shell, and it was
   drawing its two most important controls in a shape the shell does not use. The radius is the only
   thing that changes: the padding, the border width and the swap-must-not-move rule below are all
   untouched, because signin.js promotes one of these to default at runtime and a promotion that
   resizes a button moves a hit target somebody is already aiming at (D258).

   The white on the primary is `--card-background` rather than a literal #ffffff. Both are white in
   the light palette; in the dark one #ffffff on a light-green accent is a contrast failure, and the
   token is the card's own ground, which is what a filled control's label should be sitting on. It
   matches .control-pill[data-default="true"] in app.css, which is the same button in the shell. */
.signin-primary,
.signin-secondary
{
	font: inherit;
	padding: .45rem 1rem;
	border-radius: 999px;
	cursor: pointer;
	border: 1px solid transparent;
	text-decoration: none;

	/* The system height (app.css's --control-height), so the two buttons and the address field above
	   them are one height. `inline-flex` rather than `inline-block` because a min-height on an
	   inline-block leaves the label at the top of the box rather than centred in it. */
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: var( --control-height );
}

.signin-primary
{
	background: var( --accent );
	color: var( --card-background );
	border-color: var( --accent );
}

.signin-secondary
{
	background: transparent;
	color: var( --ink );
	border-color: var( --rule );
}

.signin-secondary:hover { border-color: var( --ink-quiet ); }

.signin-primary:hover
{
	background: color-mix( in srgb, var( --accent ) 85%, var( --ink ) );
	border-color: color-mix( in srgb, var( --accent ) 85%, var( --ink ) );
}

.signin-actions
{
	margin-bottom: 1rem;
}

/* The sign out is a POST and therefore a <form>, and a form is a block element -- left alone it
   takes a line of its own and the dock has one button on it. `display: contents` makes the button
   a direct child of the flex row, which is what .pin-form does for the same reason. */
.signin-signout-form { display: contents; }


/* ---------------------------------------------------------------------------------------------
   The action dock (D258).

   Jon's convention, stated for the whole page rather than for this one card: **the buttons sit next
   to each other in the bottom right corner, and what the page is currently saying sits above them.**

   Two properties are doing the work. `align-self: stretch` is the one that is easy to miss --
   `.signin-email-form` is a column with `align-items: flex-start`, so without it this dock would
   shrink to its contents and `flex-end` would have nothing to push against, leaving the buttons
   wherever the text ended. And the status line is a BLOCK ABOVE the row rather than a flex sibling
   beside it, so a message arriving in the middle of a ceremony cannot resize or move the button the
   person is about to press. Nothing about that message should cost them their aim.
   --------------------------------------------------------------------------------------------- */

.signin-dock
{
	align-self: stretch;
	display: flex;
	flex-direction: column;
	gap: .7rem;
	margin-top: .9rem;
}

.signin-buttons
{
	display: flex;
	flex-wrap: wrap;
	justify-content: flex-end;
	align-items: center;
	gap: .5rem;
}

/* Wrapping, not a breakpoint -- the same reasoning `item.css` records for the tool areas. When the
   pair cannot fit, they stack; `justify-content` still holds them to the right edge, so the corner
   is the corner at every width and there is no viewport query guessing at a container's size. */


/* ---------------------------------------------------------------------------------------------
   The status line.

   **This is the element that used to be unstyled**, and unstyled was the whole bug: `.passkey-status`
   carried no declarations at all, so "Waiting for your device…" arrived as bare body text hanging
   under the form with nothing around it. Jon's reading of it was that it looked like a render error,
   which is exactly right -- text with no frame in an interface where everything else has one reads
   as something that escaped rather than something that was said.

   It borrows the notice vocabulary above rather than inventing a second one: same radius, same
   padding rhythm, same quiet ink. A person should not have to learn two shapes for "the page is
   telling you something".
   --------------------------------------------------------------------------------------------- */

.signin-status
{
	margin: 0;
	padding: .55rem .8rem;
	border-radius: .4rem;
	border: 1px solid var( --rule );
	background: var( --card-background );
	color: var( --ink-quiet );
	font-size: var( --text-base );
	line-height: 1.45;
}

/* A failure is the one state that earns colour. It is the warning tone the notices already use, so
   the page has one idea of "this went wrong" rather than a passkey-shaped exception to it.

   The modifier is `passkey-status-failed` because that is the class passkey.js toggles, and
   passkey.js serves BOTH this page and the settings view. One toggle, two base elements, each
   stylesheet saying what the modifier means on its own element -- rather than a second class name
   that would have to be kept in step with the first. */
.signin-status.passkey-status-failed
{
	background: var( --warning-quiet );
	border-color: transparent;
	color: var( --warning );
}


/* ---------------------------------------------------------------------------------------------
   Which button is the default one.

   The tone classes are swapped at runtime by signin.js -- passkey is the default until the address
   field is engaged, and then the email button is. Both buttons therefore have to be able to hold
   either tone, which they already can, and the ONE thing this file adds is that the swap must not
   move anything: a default button and a secondary button must occupy identical space, or the pair
   jitters sideways every time focus enters or leaves the field.

   `.signin-primary` and `.signin-secondary` already share their padding and radius and differ only
   in colour and border-colour, so this holds by construction. The rule below states it rather than
   leaving it to be rediscovered, and the transition keeps the change from reading as a flicker.
   --------------------------------------------------------------------------------------------- */

.signin-buttons .signin-primary,
.signin-buttons .signin-secondary
{
	transition: background-color .12s ease, color .12s ease, border-color .12s ease;
}

@media ( prefers-reduced-motion: reduce )
{
	.signin-buttons .signin-primary,
	.signin-buttons .signin-secondary
	{
		transition: none;
	}
}

/* ---------------------------------------------------------------------------------------------
   The honeypot.

   Positioned off-canvas rather than `display: none`. That distinction is the whole trick: a
   `display: none` field is trivially detectable by any script that reads computed style, and some
   password managers skip it while others do not. A field that is simply somewhere else on the plane
   is present, focusable in principle, and invisible in practice -- so a script that fills every
   input still fills it.

   `aria-hidden` on the wrapper and `tabindex="-1"` on the input keep it away from assistive
   technology and away from the tab order, which is what stops it being a trap for a real person
   using a screen reader. A honeypot that catches a blind user is not a honeypot, it is a bug.
   --------------------------------------------------------------------------------------------- */

.signin-trap
{
	position: absolute;
	left: -9999px;
	top: auto;
	width: 1px;
	height: 1px;
	overflow: hidden;
}


/* ---------------------------------------------------------------------------------------------
   The SMS block.

   Ships with the `hidden` attribute; signin.js removes it on phone-class devices, and signin.php
   omits it on a render that follows an SMS request so a "Could not send" notice appears beside the
   field it is about. Nothing here fights that attribute -- there is no `display` on .signin-sms
   itself -- because two mechanisms for one piece of visibility is how an element ends up shown when
   it should not be.
   --------------------------------------------------------------------------------------------- */

.signin-sms
{
	margin-top: 1.6rem;
	padding-top: 1.4rem;
	border-top: 1px solid var( --rule );
}

.signin-sms h2
{
	margin-bottom: .3rem;
}

.signin-sms-form
{
	display: flex;
	flex-direction: column;
	gap: .5rem;
	margin-top: .8rem;
}

.signin-sms-form label
{
	font-size: var( --text-base );
	color: var( --ink-quiet );
}

.signin-sms-form input[ type="tel" ]
{
	padding: .6rem .7rem;
	font: inherit;
	color: var( --ink );
	background: var( --field-background, var( --card-background ) );
	border: 1px solid var( --rule );
	border-radius: .3rem;
}

.signin-sms-form input[ type="tel" ]:focus
{
	outline: 2px solid var( --accent );
	outline-offset: 1px;
}


/* ---------------------------------------------------------------------------------------------
   The identity block (D259): what the installation says about itself, above the form.

   Quiet by design. A stranger's first question is *what is this?* and the answer is two short
   lines; the form beneath them is what the page is FOR, so nothing here competes with it for the
   eye. That is why both rules below reach for --ink-quiet rather than --ink.
   --------------------------------------------------------------------------------------------- */

/* The namespace that appears in every URN this installation issues. Monospaced because it is an
   identifier a person may need to copy or compare character by character, not prose. */
/* The tagline, directly under the wordmark (D316). Body ink rather than the quiet tone the slug and
   description wear below it, because it is the product's own line and the other two are the
   installation's; a touch of tracking so the short phrase does not read as a stray caption. */
.front-tagline
{
	margin: 0;
	font-size: var( --text-lg );
	letter-spacing: .02em;
	color: var( --ink );
	text-align: center;
}

.front-slug
{
	margin: 0;
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-size: var( --text-sm );
	color: var( --ink-quiet );
	text-align: center;
}

.front-description
{
	margin: 0 0 .5rem;
	color: var( --ink-quiet );
	text-align: center;
}

/* The honest description of Q10, at the foot of the page: there is no published surface yet, so
   there is nothing here to list. Separated by a rule because it is a statement about the
   installation rather than a step in signing in. */
.front-note
{
	margin: 1rem 0 0;
	padding-top: 1.25rem;
	border-top: 1px solid var( --rule );
	font-size: var( --text-sm );
	color: var( --ink-quiet );
}


/* ---------------------------------------------------------------------------------------------
   THE TOUCH-SCREEN FONT FLOOR, the sign-in page.

   app.css states the rule and the whole argument for it: under a coarse pointer no text-entry
   control may compute below 16px, because iOS Safari zooms the page in on focusing one and never
   zooms back out. This file loads AFTER app.css, so every field it sizes here wins the tie against
   that floor and has to repeat it. This is the first control anybody touches on a phone:
   before the floor, tapping the email field zoomed the page before a character had been typed.
   --------------------------------------------------------------------------------------------- */

@media ( pointer: coarse )
{
	.signin-email-form input[ type="email" ],
	.signin-sms-form input[ type="tel" ]
	{
		font-size: max( 16px, 1em );
	}
}


/* A closed installation (D508): the same card, with the warning's colour down its edge so it reads
   before the form under it. */
.signin-closed { border-left: 4px solid var( --warning ); }
.signin-closed h1 { margin-top: 0; }
.signin-closed-message > :first-child { margin-top: 0; }
