/* Only what Bootstrap does not provide.
 *
 * Colours, in every theme, come from Bootstrap 5. The theme is switched by
 * data-bs-theme on the html element, which Bootstrap 5.3 reads to repaint its own
 * components, so there is no second palette written out here. What is left below
 * is either layout Bootstrap has no opinion on, or the spinner and the confirm
 * dialog, which are this application's own components and follow the theme
 * through Bootstrap's variables.
 */


/* ---------------------------------------------------------------------------
   Theme tokens.

   Bootstrap 5.3 reads data-bs-theme and builds every component from these
   variables, so the whole palette is stated once here rather than component by
   component. --app-surface is the raised colour: cards, tables and inputs sit on
   it, the page sits behind it, and that difference is what gives the screens
   their depth.
   --------------------------------------------------------------------------- */

[data-bs-theme="light"] {
	--bs-body-bg: #f6f8fb;
	--bs-body-bg-rgb: 246, 248, 251;
	--bs-tertiary-bg: #ffffff;
	--bs-tertiary-bg-rgb: 255, 255, 255;
	--bs-border-color: #e4e9f0;
	--app-surface: #ffffff;
}

[data-bs-theme="dark"] {
	--bs-body-bg: #0b1220;
	--bs-body-bg-rgb: 11, 18, 32;
	--bs-body-color: #e5edf8;
	--bs-secondary-color: #93a3bd;
	--bs-border-color: #1e2a45;
	--bs-tertiary-bg: #0d1526;
	--bs-tertiary-bg-rgb: 13, 21, 38;
	--app-surface: #101a2f;
}

.card    { --bs-card-bg: var(--app-surface); }
.table   { --bs-table-bg: var(--app-surface); }

[data-bs-theme="dark"] .form-control,
[data-bs-theme="dark"] .form-select {
	background-color: var(--app-surface);
}

/* ---------------------------------------------------------------------------
   Small pieces the design uses that Bootstrap has no component for.
   --------------------------------------------------------------------------- */

/* The numbered step beside each section heading. */
.step-badge {
	width: 1.6rem;
	height: 1.6rem;
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	background-color: var(--bs-primary);
	color: #fff;
	font-size: 0.78rem;
	font-weight: 600;
}

/* A tinted rounded square holding an icon, used beside the SIM and date fields. */
.icon-square {
	width: 2.25rem;
	height: 2.25rem;
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: 0.55rem;
	background-color: rgba(var(--bs-primary-rgb), 0.12);
	color: var(--bs-primary);
}

.icon-square.icon-square-success {
	background-color: rgba(var(--bs-success-rgb), 0.15);
	color: var(--bs-success);
}

/* The card's own icon: flat and tinted in the light theme, and the gradient the
   design uses on the dark one, where a flat tint disappears. */
.header-icon {
	width: 3.25rem;
	height: 3.25rem;
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: 0.9rem;
	font-size: 1.35rem;
	background-color: rgba(var(--bs-primary-rgb), 0.12);
	color: var(--bs-primary);
}

[data-bs-theme="dark"] .header-icon {
	background-image: linear-gradient(135deg, #4f7cf7, #7c5cf5);
	color: #fff;
}

/* Each period choice is a tile rather than a bare radio, so the hit area is the
   whole box and the chosen one is unmistakable. :has keeps the selected state in
   CSS; where a browser lacks it the radio itself still shows the choice. */
.option-tile {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	min-width: 9.5rem;
	padding: 0.55rem 0.85rem;
	border: 1px solid var(--bs-border-color);
	border-radius: 0.6rem;
	background-color: var(--app-surface);
	cursor: pointer;
}

.option-tile:hover {
	border-color: rgba(var(--bs-primary-rgb), 0.55);
}

.option-tile:has(input:checked) {
	border-color: var(--bs-primary);
	box-shadow: 0 0 0 0.18rem rgba(var(--bs-primary-rgb), 0.18);
}

/* Bootstrap draws an unchosen radio with a 1px border at 25% opacity, which on
   these tiles is close to invisible in either theme, and on a screen where
   nothing is selected by default the empty state has to be legible. The ring is
   thicker and takes the secondary text colour, which is defined per theme. */
.option-tile .form-check-input {
	margin: 0;
	float: none;
	width: 1.15em;
	height: 1.15em;
	border-width: 2px;
	border-color: var(--bs-secondary-color);
}

.option-tile .tile-note {
	font-size: 0.75rem;
	color: var(--bs-secondary-color);
}

/* The panel showing what the validity becomes, tinted so it reads as the result
   rather than another input. */
.result-panel {
	background-color: rgba(var(--bs-success-rgb), 0.07);
	border: 1px solid rgba(var(--bs-success-rgb), 0.25);
}

/* ---------------------------------------------------------------------------
   Loading spinner.
   --------------------------------------------------------------------------- */

#loader {
	border: 12px solid var(--bs-secondary-bg);
	border-radius: 50%;
	border-top: 12px solid var(--bs-emphasis-color);
	width: 70px;
	height: 70px;
	animation: spin 1s linear infinite;
}

@keyframes spin {
	100% {
		transform: rotate(360deg);
	}
}

.center {
	position: absolute;
	top: 0;
	bottom: 0;
	left: 0;
	right: 0;
	margin: auto;
}

/* ---------------------------------------------------------------------------
   The footer is fixed to the bottom of the viewport, so every page has to keep
   that much room free or its last controls sit underneath it and cannot be
   scrolled into view. min-height rather than height, so the copyright line may
   wrap on a narrow screen without spilling out of its own box. The fill comes
   from bg-body-tertiary on the element.
   --------------------------------------------------------------------------- */

/* Bootstrap's body is pure white in the light theme, which is hard going on
   screens that are mostly grid. The page drops to Bootstrap's tertiary surface
   and the tables and cards keep the body colour, so the data reads as raised
   rather than everything being one sheet. Both are Bootstrap's own tokens, so
   the dark theme follows without a second rule. */
/* The page colour is stated on the root as well as the body. Bootstrap paints
   only the body, so where the content is shorter than the viewport the area
   below it fell back to the browser's own canvas, which under color-scheme dark
   is a grey that belongs to no palette here. */
html,
body {
	background-color: var(--bs-body-bg);
}

body {
	padding-bottom: 80px;
}

.footer {
	position: fixed;
	bottom: 0;
	width: 100%;
	min-height: 60px;
}

/* ---------------------------------------------------------------------------
   Navbar spacing. Bootstrap packs the links up against the brand at .5rem
   apart, which reads as one run-on string of words. Spacing only: the fill and
   every colour on it are Bootstrap's.
   --------------------------------------------------------------------------- */

.navbar-expand-lg .navbar-nav .nav-link {
	padding-left: 0.9rem;
	padding-right: 0.9rem;
}

.navbar-expand-lg .navbar-nav .nav-item + .nav-item {
	margin-left: 0.15rem;
}

.navbar-expand-lg .navbar-nav.ms-auto {
	padding-left: 1.5rem;
}

/* ---------------------------------------------------------------------------
   Brand logo. Bootstrap sizes the brand from its text; with an image it needs a
   height, and the navbar's own padding is enough vertical room at this size.
   --------------------------------------------------------------------------- */

.navbar-brand img {
	height: 34px;
	width: auto;
}

/* ---------------------------------------------------------------------------
   Confirm dialog. Not a Bootstrap component, so it is laid out here, but its
   surface and text follow the theme through Bootstrap's own variables.
   --------------------------------------------------------------------------- */

.confirm-dialog {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background-color: rgba(0, 0, 0, 0.5);
	display: flex;
	align-items: center;
	justify-content: center;
	z-index: 1050;
}

.confirm-dialog[hidden] {
	display: none;
}

.confirm-dialog-box {
	background-color: var(--bs-body-bg);
	color: var(--bs-body-color);
	border: 1px solid var(--bs-border-color);
	border-radius: 6px;
	padding: 20px;
	max-width: 520px;
	margin: 16px;
	box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
}

/*
 * Update SIM is a long form of otherwise identical text boxes. Bootstrap's card
 * header is quiet enough that a dozen of them down one page stop registering as
 * boundaries, so the group headers carry a little more weight and an accent rule
 * on the leading edge. Colours are Bootstrap's own tokens, not new ones, so both
 * themes follow.
 */
.form-section > .card-header {
	background-color: var(--bs-secondary-bg);
	border-left: 3px solid var(--bs-primary);
	font-weight: 600;
	letter-spacing: .01em;
	display: flex;
	align-items: center;
	gap: .5rem;
}

.form-section > .card-header .section-note {
	font-weight: 400;
}

/* The same boxes on a white card read as one grey mass; a definite border makes
   each field its own object. */
.form-section .form-control,
.form-section .form-select {
	border-color: var(--bs-border-color);
}

/*
 * Read only values are shown as text rather than as a greyed box. A box is an
 * invitation to type whatever colour it is, and a disabled looking one mostly
 * reads as "editable, but not yet". Removing the frame is the clearer signal,
 * and the text stays selectable so it can still be copied.
 */
.form-section .form-control-plaintext {
	padding-left: 0;
	border-bottom: 1px dashed var(--bs-border-color);
	border-radius: 0;
	color: var(--bs-secondary-color);
	cursor: default;
}

.form-section .form-label {
	font-weight: 500;
	margin-bottom: .25rem;
}

/* A date field is a picker with the stored text beneath it, so the raw value is
   never hidden when the calendar cannot show it. */
.date-field .stored-as {
	font-size: .8125rem;
}

/* The save is a long way from the top of this form. */
.form-actions {
	position: sticky;
	bottom: 0;
	z-index: 5;
	background-color: var(--bs-body-bg);
	border-top: 1px solid var(--bs-border-color);
}
