@import url("https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@500;600;700&display=swap");

:root {
    --primaryText: #171716;
    --secondaryText: #625f59;
    --inverseText: #f7f3e9;
    --pageBackground: #f7f3e9;
    --surfaceBackground: #e3ddd0;
    --hoverBackground: #ece7dc;
    --selectedBackground: #2d2d2a;
    --selectedControlBackground: #2d2d2a;
    --primaryButtonBackground: #2d2d2a;
    --primaryButtonHoverBackground: #55534e;
    --defaultBorder: #171716;
    --inverseBorder: #f7f3e9;
    --focusRing: #55534e;
    --accentFill: #bd2725;
    --hatchEdgeWidth: 24px;
    --hatchLineWidth: 1px;
    --hatchPeriod: 4px;
}

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

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

body {
    font-family: Arial, Helvetica, sans-serif;
    margin: 0;
    background-color: var(--pageBackground);
    color: var(--primaryText);
    cursor: var(--dotCursor), auto;
}

/* Browser stylesheets give these their own cursors; the dot applies everywhere. */
a,
button,
input,
label,
select,
summary,
textarea {
    cursor: inherit;
}

/* The cursor is a black dot. js/effects/cursor.js writes the cursor image into
   --dotCursor and --dotCursorOnDark and swells it on click. Dark surfaces set
   --dotSurface: dark so the OS cursor image and the swell both pick the light
   dot. */
.remember-input:checked,
.btn-primary,
.contact-list-item:active,
.contact-list-item.is-active,
.btn-add-contact:active,
.btn-add-contact.is-active,
.contact-list-add.is-active .btn-add-contact,
.contact-view-avatar,
.contact-view-copy:hover,
.contact-view-copy.is-copied,
.contact-view-field-action:active,
.btn-delete-contact:active,
.btn-dialog-delete,
.login-blob {
    --dotSurface: dark;
    cursor: var(--dotCursorOnDark), auto;
}

.hero-container {
    min-height: 100vh;
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
}

.hero-inner {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: stretch;
}

.hero-image {
    flex: 0 0 500px;
    overflow: visible;
}

.hero-image img {
    display: block;
    padding-top: 0px;
    width: 100%;
    height: auto;
    transform: translateY(84px);
    image-rendering: crisp-edges;
    image-rendering: pixelated;
}

/* A red blob behind the login hero, mostly off the page's bottom-right corner
   so only its edge shows. It never starts left of the hero's center line,
   which keeps it off Monke: red behind the transparent drawing hides its ink
   lines. The hero is lifted above it (.hero-inner), and only the painted shape
   takes presses, which js/effects/blob.js turns into a wobble. Tapping it rapidly
   grows it over the whole page, so it may paint past its own box. The layer is
   pinned to the window, not the hero, so the cover reaches every edge however
   tall the page is. */
.login-blobs {
    position: fixed;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
}

.login-blob {
    position: absolute;
    top: calc(100% - 360px);
    left: max(calc(50% + 60px), calc(100% - 420px));
    width: 760px;
    height: 760px;
    overflow: visible;
    fill: var(--accentFill);
    touch-action: manipulation;
}

.login-blob path {
    pointer-events: visiblePainted;
}

/* js/effects/blob.js sets --blobCover from 0, where the hero is still clear of the
   blob, to 1, where the blob has swallowed it, and only once a blob is big
   enough to hide it. The hero fades out across that and ignores presses, so
   taps keep landing on the blob. */
html.blob-covering .hero-inner {
    opacity: calc(1 - var(--blobCover, 0));
    pointer-events: none;
}

.login-container {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 12px;
    width: 400px;
    padding: 12px;
    border: 1px solid var(--defaultBorder);
    background-color: var(--surfaceBackground);
    font-family: "Cormorant Garamond", Georgia, serif;
    font-size: 16px;
}

.login-container > form {
    width: 100%;
}

.login-container input,
.login-container button {
    font: inherit;
}

.login-title {
    width: 100%;
    font-size: 24px;
    white-space: nowrap;
}

.login-form {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width: 100%;
    gap: 12px;
}

.login-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
}

.login-row a {
    color: var(--primaryText);
    text-decoration: none;
}

.remember-label {
    display: flex;
    align-items: center;
    gap: 8px;
}

.remember-input {
    appearance: none;
    -webkit-appearance: none;
    width: 20px;
    height: 20px;
    margin: 0;
    border: 1px solid var(--defaultBorder);
    border-radius: 0;
    background-color: var(--pageBackground);
}

.form-input,
.btn-primary {
    width: 100%;
    padding: 12px;
    border: 1px solid var(--defaultBorder);
}

.remember-input:checked {
    background-color: var(--selectedControlBackground);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 8l3 3 7-7' fill='none' stroke='%23f7f3e9' stroke-width='2'/%3E%3C/svg%3E");
    background-position: center;
    background-repeat: no-repeat;
    background-size: 14px;
}

.login-divider {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 8px 0;
}

.login-divider::before,
.login-divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background-color: var(--defaultBorder);
}

.form-input {
    background-color: var(--pageBackground);
}

.form-input:focus {
    outline: 2px solid var(--focusRing);
    outline-offset: 1px;
    box-shadow: none;
}

.btn-primary {
    background-color: var(--primaryButtonBackground);
    color: var(--inverseText);
}

.btn-primary:hover {
    background-color: var(--primaryButtonHoverBackground);
}

/* Sign Up navigates rather than acts, so it is a link wearing the button style. */
a.btn-primary {
    display: block;
    text-align: center;
    text-decoration: none;
}

/* Why a login attempt failed, filled in by js/code.js. */
.login-error {
    width: 100%;
    margin: 0;
    color: var(--accentFill);
    font-size: 15px;
}

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

/* The sign-up page stacks its card over the "Already have an account?" line,
   so its hero runs as a column where the login page's runs as a row. */
.signup-page .hero-container {
    flex-direction: column;
    gap: 12px;
}

.login-switch {
    margin: 0;
    font-family: "Cormorant Garamond", Georgia, serif;
    font-size: 16px;
    text-align: center;
}

.login-switch a {
    color: var(--primaryText);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.login-switch a:focus-visible {
    outline: 2px solid var(--focusRing);
    outline-offset: 1px;
}

.form-input::placeholder,
.contact-search-input::placeholder {
    color: var(--secondaryText);
    opacity: 1;
}

/* The illustrated login composition is desktop-only. On smaller viewports the
   shared login/sign-up card becomes fluid and gets its breathing room from the
   page instead of relying on a fixed 400px width. */
@media (max-width: 1023px) {
    .hero-container {
        padding: 24px;
    }

    .hero-inner {
        width: 100%;
        justify-content: center;
    }

    .hero-image {
        display: none;
    }

    .login-container {
        width: min(400px, 100%);
    }

    .login-blob {
        top: calc(100% - 220px);
        left: calc(100% - 260px);
        width: 520px;
        height: 520px;
    }
}

@media (max-width: 767px) {
    .hero-container {
        padding: 16px;
    }

    .login-title {
        line-height: 1.1;
        white-space: normal;
    }

    .login-row {
        flex-wrap: wrap;
        gap: 12px;
    }

    .login-blob {
        top: calc(100% - 160px);
        left: calc(100% - 190px);
        width: 400px;
        height: 400px;
    }
}

.dashboard-container {
    min-height: 100vh;
    width: 100%;
    display: flex;
}

.dashboard-inner {
    display: flex;
    align-items: stretch;
    min-width: 0;
    width: 100%;
}

.contact-list-section {
    position: relative;
    flex: 0 0 300px;
    display: flex;
    flex-direction: column;
    border-right: 1px solid var(--defaultBorder);
    /* background-color: var(--surfaceBackground); */
}

/* Second rule of the divider, 2px outside the border. */
.contact-list-section::after {
    content: "";
    position: absolute;
    top: 0;
    right: -4px;
    bottom: 0;
    width: 1px;
    background-color: var(--defaultBorder);
    pointer-events: none;
}

/* Hatched edges with an inset surface plate, shared by the sidebar header and the spacer. */
.contact-list-header,
.contact-list-spacer {
    position: relative;
    background-image: repeating-linear-gradient(
        -45deg,
        var(--defaultBorder) 0 var(--hatchLineWidth),
        transparent var(--hatchLineWidth) var(--hatchPeriod)
    );
}

.contact-list-header::before,
.contact-list-spacer::before {
    content: "";
    position: absolute;
    inset: 0 var(--hatchEdgeWidth);
    border-inline: 1px solid var(--defaultBorder);
    background-color: var(--surfaceBackground);
    pointer-events: none;
}

.contact-list-spacer {
    flex: 1;
}

.contact-list-header {
    min-height: 58px;
    padding: 12px;
    border-bottom: 1px solid var(--defaultBorder);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: "Cormorant Garamond", Georgia, serif;
    font-size: 18px;
    font-weight: 600;
}

.contact-list-header h2 {
    position: relative;
    margin: 0;
}

.contact-list-search {
    position: relative;
    padding: 12px;
}

.contact-list-search::after {
    content: "";
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    border-bottom: 1px solid var(--defaultBorder);
    pointer-events: none;
    transition: right 200ms ease, left 200ms ease;
}

.contact-list-search.is-list-start::after {
    right: 12px;
    left: 12px;
}

.contact-search-input {
    width: 100%;
    padding: 12px;
    border: 1px solid var(--defaultBorder);
    border-radius: 0;
    background-color: var(--pageBackground);
    font-family: "Cormorant Garamond", Georgia, serif;
    font-size: 16px;
}

.contact-search-input:focus {
    outline: 2px solid var(--focusRing);
    outline-offset: 1px;
    box-shadow: none;
}

.contact-search-input::-webkit-search-cancel-button {
    width: 18px;
    height: 18px;
    margin: 0;
    -webkit-appearance: none;
    appearance: none;
    background-color: var(--primaryText);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 6l12 12M18 6L6 18' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 6l12 12M18 6L6 18' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
}

.contact-list-items {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin: 0;
    padding: 12px;
    border-bottom: 1px solid var(--defaultBorder);
    list-style: none;
}

.contact-list-item {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 12px;
    border: 1px solid var(--defaultBorder);
    border-radius: 0;
    background-color: var(--pageBackground);
    color: var(--primaryText);
    font-family: "Cormorant Garamond", Georgia, serif;
    font-size: 16px;
    text-align: left;
}

.contact-list-item:hover {
    background-color: var(--hoverBackground);
}

.contact-list-item:active,
.contact-list-item.is-active {
    background-color: var(--selectedBackground);
    color: var(--inverseText);
}

.contact-list-item:active .contact-list-avatar,
.contact-list-item.is-active .contact-list-avatar {
    border-color: var(--inverseBorder);
}

.contact-list-item:focus-visible {
    outline: 2px solid var(--focusRing);
    outline-offset: 2px;
}

.contact-list-entry {
    display: flex;
}

.contact-list-avatar {
    display: grid;
    place-items: center;
    flex: 0 0 36px;
    width: 36px;
    height: 36px;
    border: 1px solid var(--defaultBorder);
    font-weight: bold;
    line-height: 1;
}

.contact-list-name-text {
    display: block;
    font-size: 1.17em;
    font-weight: bold;
    overflow-wrap: anywhere;
}

.contact-list-name {
    flex: 1;
    min-width: 0;
}

.contact-list-chevron,
.btn-add-contact-text {
    display: none;
}

.delete-contact-icon,
.add-contact-icon {
    width: 18px;
    height: 18px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.delete-contact-icon {
    stroke-width: 1.5;
}

.contact-list-add {
    position: relative;
    display: flex;
    padding: 12px;
    border-top: 1px solid transparent;
}

.contact-list-add::before {
    content: "";
    position: absolute;
    top: -1px;
    right: 0;
    left: 0;
    border-top: 1px solid var(--defaultBorder);
    pointer-events: none;
    transition: right 200ms ease, left 200ms ease;
}

.contact-list-add.is-list-end::before {
    right: 12px;
    left: 12px;
}

.btn-add-contact {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    min-height: 62px;
    /* padding: 0 12px; */
    border: 2px dashed var(--defaultBorder);
    background-color: var(--pageBackground);
    color: var(--primaryText);
    font-family: "Cormorant Garamond", Georgia, serif;
    font-size: 16px;
}

.btn-add-contact:hover {
    border: 1px solid;
    background-color: var(--hoverBackground);
}

.btn-add-contact:active,
.btn-add-contact.is-active,
.contact-list-add.is-active .btn-add-contact {
    background-color: var(--primaryButtonBackground);
    color: var(--inverseText);
}

.contact-list-logout {
    padding: 12px;
    border-top: 1px solid var(--defaultBorder);
}

.contact-list-logout form {
    margin: 0;
}

.logout-button {
    width: 100%;
    font-family: "Cormorant Garamond", Georgia, serif;
    font-size: 16px;
}

.mobile-back-button {
    display: none;
}

.contact-details {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.contact-workspace-panel {
    --panel-gutter: 24px;
    --panel-heading-y: 20px;
    --detail-row-y: 22px;
    --form-field-y: 12px;
    --panel-control-height: 52px;

    width: min(720px, calc(100% - 72px));
    /* Top margin puts the outer frame level with the sidebar search box: 58px header + 12px padding + 5px frame offset. */
    margin: 75px auto 36px;
    border: 1px solid var(--defaultBorder);
    outline: 1px solid var(--defaultBorder);
    outline-offset: 2px;
    background-color: var(--pageBackground);
    font-family: "Cormorant Garamond", Georgia, serif;
    font-size: 16px;
}

.contact-details-view {
    --contact-view-avatar-size: 64px;
}

.contact-panel-heading {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: var(--panel-heading-y) var(--panel-gutter);
    border-bottom: 1px solid var(--defaultBorder);
}

.contact-panel-heading::before,
.contact-panel-heading::after {
    content: "";
    flex: 1;
    min-width: 20px;
    border-top: 1px solid var(--defaultBorder);
}

.contact-panel-heading h2 {
    flex: none;
    margin: 0;
    font-size: clamp(27px, 4vw, 36px);
    font-weight: 700;
    line-height: 1;
    text-align: center;
}

.contact-view-identity {
    display: flex;
    align-items: center;
    gap: 20px;
    padding: calc(var(--panel-heading-y) + 4px) var(--panel-gutter);
    border-bottom: 1px solid var(--defaultBorder);
    background-color: var(--pageBackground);
    color: var(--primaryText);
}

.contact-view-avatar {
    display: grid;
    place-items: center;
    flex: 0 0 var(--contact-view-avatar-size);
    width: var(--contact-view-avatar-size);
    height: var(--contact-view-avatar-size);
    border: 1px solid var(--defaultBorder);
    border-radius: 50%;
    background-color: var(--selectedBackground);
    color: var(--inverseText);
    font-size: 24px;
    font-weight: bold;
    line-height: 1;
}

.contact-view-title {
    flex: 1;
    min-width: 0;
}

.contact-view-identity h3 {
    margin: 0;
    font-size: 32px;
    font-weight: 600;
    line-height: 1.05;
    overflow-wrap: anywhere;
}

.contact-view-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 2px 16px;
    margin: 4px 0 0;
    color: var(--secondaryText);
}

.contact-view-meta-item {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 2px 6px;
}

.contact-view-meta dt {
    white-space: nowrap;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 10px;
    font-weight: bold;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.contact-view-meta dd {
    margin: 0;
    font-size: 15px;
    font-weight: 600;
    white-space: nowrap;
}

.contact-view-fields {
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0 var(--panel-gutter);
    list-style: none;
}

.contact-view-field {
    display: grid;
    grid-template-columns: var(--contact-view-avatar-size) minmax(0, 1fr) auto;
    align-items: center;
    gap: 20px;
    padding: var(--detail-row-y) 0;
    border-bottom: 1px solid var(--defaultBorder);
}

.contact-view-copy {
    display: grid;
    place-items: center;
    justify-self: center;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 1px solid var(--defaultBorder);
    background-color: var(--surfaceBackground);
    color: var(--primaryText);
}

.contact-view-copy:hover,
.contact-view-copy.is-copied {
    border-color: var(--selectedBackground);
    background-color: var(--selectedBackground);
    color: var(--inverseText);
}

.contact-view-copy svg {
    width: 18px;
    height: 18px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.contact-view-copied-icon,
.contact-view-copy.is-copied .contact-view-copy-icon {
    display: none;
}

.contact-view-copy.is-copied .contact-view-copied-icon {
    display: block;
}

.contact-view-field-text {
    min-width: 0;
}

.contact-view-label {
    display: block;
    margin-bottom: 2px;
    color: var(--secondaryText);
    font-family: Arial, Helvetica, sans-serif;
    font-size: 11px;
    font-weight: bold;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.contact-view-value {
    display: block;
    overflow: hidden;
    font-size: 18px;
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.contact-view-field-action {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 36px;
    padding: 0 12px;
    background-color: var(--pageBackground);
    color: var(--primaryText);
    font-size: 16px;
    text-decoration: none;
}

.contact-view-field-action:hover {
    background-color: var(--hoverBackground);
}

.contact-view-field-action:active {
    background-color: var(--selectedBackground);
    color: var(--inverseText);
}

.contact-view-field-action-arrow {
    font-family: Arial, Helvetica, sans-serif;
    font-size: 14px;
    line-height: 1;
}

.contact-view-footer {
    padding: var(--panel-heading-y) var(--panel-gutter) calc(var(--panel-heading-y) + 4px);
}

.btn-contact-edit {
    width: 100%;
    min-height: var(--panel-control-height);
    padding: 12px;
    border: 1px solid var(--defaultBorder);
    background-color: transparent;
    color: var(--primaryText);
    font-family: "Cormorant Garamond", Georgia, serif;
    font-size: 19px;
}

.btn-contact-edit:hover {
    background-color: var(--hoverBackground);
}

.btn-contact-edit:active {
    background-color: var(--selectedBackground);
    color: var(--inverseText);
}

.contact-view-copy:focus-visible,
.contact-view-field-action:focus-visible {
    outline: 2px solid var(--focusRing);
    outline-offset: 2px;
}

.btn-contact-edit:focus-visible,
.btn-contact-cancel:focus-visible,
.btn-delete-contact:focus-visible {
    outline: 2px solid var(--focusRing);
    outline-offset: 2px;
}

.contact-details-form,
.contact-edit-form {
    display: none;
}

.dashboard-container.is-adding .contact-details-view,
.dashboard-container.is-adding .contact-edit-form,
.dashboard-container.is-editing .contact-details-view,
.dashboard-container.is-editing .contact-details-form {
    display: none;
}

.dashboard-container.is-adding .contact-details-form {
    display: block;
}

.dashboard-container.is-editing .contact-edit-form {
    display: block;
}

.contact-details-bottom-border {
    /* border-bottom: 1px solid var(--defaultBorder); */
}

.contact-form-fields {
    display: flex;
    flex-direction: column;
    padding: 4px var(--panel-gutter) calc(var(--panel-heading-y) - 4px);
    font-family: "Cormorant Garamond", Georgia, serif;
    font-size: 16px;
}

.contact-form-field {
    padding: var(--form-field-y) 0 calc(var(--form-field-y) + 2px);
}

.contact-form-field label {
    display: block;
    margin-bottom: 6px;
    color: var(--secondaryText);
    font-family: Arial, Helvetica, sans-serif;
    font-size: 11px;
    font-weight: bold;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.contact-form-field .form-input {
    min-height: var(--panel-control-height);
    border-radius: 0;
    font-family: "Cormorant Garamond", Georgia, serif;
    font-size: 19px;
    font-weight: 600;
}

.contact-form-footer {
    padding: 0 var(--panel-gutter) var(--panel-heading-y);
}

.contact-form-footer .btn-primary {
    min-height: var(--panel-control-height);
    border-radius: 0;
    font-family: "Cormorant Garamond", Georgia, serif;
    font-size: 19px;
}

.contact-edit-actions {
    display: grid;
    gap: 8px;
}

.btn-contact-cancel {
    min-height: 40px;
    border: 0;
    background: transparent;
    color: var(--primaryText);
    font-family: "Cormorant Garamond", Georgia, serif;
    font-size: 18px;
}

.btn-contact-cancel:hover {
    background-color: var(--hoverBackground);
}

.contact-form-danger {
    margin: 0 var(--panel-gutter);
    padding: var(--panel-heading-y) 0;
    border-top: 1px solid var(--defaultBorder);
    text-align: center;
}

.btn-delete-contact {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 44px;
    padding: 8px 12px;
    border: 1px solid transparent;
    background-color: transparent;
    color: var(--accentFill);
    font-family: "Cormorant Garamond", Georgia, serif;
    font-size: 18px;
    transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}

.btn-delete-contact:hover {
    border-color: var(--accentFill);
    background-color: color-mix(in srgb, var(--accentFill) 8%, transparent);
}

.btn-delete-contact:active {
    border-color: var(--accentFill);
    background-color: var(--accentFill);
    color: var(--inverseText);
}

.btn-delete-contact:focus-visible {
    outline-color: var(--accentFill);
}

.btn-delete-contact:disabled {
    opacity: 0.55;
}

.delete-contact-dialog {
    width: min(440px, calc(100% - 32px));
    max-height: calc(100vh - 32px);
    max-height: calc(100dvh - 32px);
    padding: 0;
    overflow: auto;
    border: 1px solid var(--defaultBorder);
    border-radius: 0;
    outline: 1px solid var(--defaultBorder);
    outline-offset: 2px;
    background-color: var(--pageBackground);
    color: var(--primaryText);
    font-family: "Cormorant Garamond", Georgia, serif;
}

.delete-contact-dialog[open] {
    animation: delete-dialog-enter 150ms ease-out;
}

.delete-contact-dialog::backdrop {
    background-color: rgb(23 23 22 / 58%);
}

.delete-dialog-content {
    padding: 24px 24px 16px;
    text-align: center;
}

.delete-dialog-content p {
    margin: 0;
}

.delete-dialog-content strong {
    font-size: 20px;
}

.delete-dialog-warning {
    margin-top: 8px !important;
    color: var(--secondaryText);
    font-family: Arial, Helvetica, sans-serif;
    font-size: 11px;
    font-weight: bold;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.delete-dialog-status {
    min-height: 1.25em;
    margin-top: 14px !important;
    color: var(--secondaryText);
    font-family: Arial, Helvetica, sans-serif;
    font-size: 14px;
}

.delete-dialog-status:empty {
    display: none;
}

.delete-dialog-status.is-error {
    color: var(--accentFill);
}

.delete-dialog-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    margin: 0;
    padding: 0 24px 24px;
}

.btn-dialog-cancel,
.btn-dialog-delete {
    min-height: 48px;
    padding: 10px 12px;
    border-radius: 0;
    font-family: "Cormorant Garamond", Georgia, serif;
    font-size: 18px;
}

.btn-dialog-cancel {
    border: 1px solid var(--defaultBorder);
    background-color: transparent;
    color: var(--primaryText);
}

.btn-dialog-cancel:hover {
    background-color: var(--hoverBackground);
}

.btn-dialog-delete {
    border: 1px solid var(--accentFill);
    background-color: var(--accentFill);
    color: var(--inverseText);
}

.btn-dialog-delete:hover {
    background-color: color-mix(in srgb, var(--accentFill) 84%, var(--primaryText));
}

.btn-dialog-cancel:focus-visible,
.btn-dialog-delete:focus-visible {
    outline: 2px solid var(--focusRing);
    outline-offset: 2px;
}

.btn-dialog-delete:focus-visible {
    outline-color: var(--accentFill);
}

.btn-dialog-cancel:disabled,
.btn-dialog-delete:disabled {
    opacity: 0.55;
}

@keyframes delete-dialog-enter {
    from {
        opacity: 0;
        transform: translateY(8px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.contact-form-status {
    min-height: 1.25em;
    margin: -8px var(--panel-gutter) 16px;
    color: var(--accentFill);
    font-size: 14px;
    text-align: center;
}

.contact-form-status:empty {
    display: none;
}

/* Keep the dashboard controls available while only the contact rows scroll.
   The mobile list screen gets its own layout in the next responsive phase. */
@media (min-width: 768px) {
    .contact-list-section {
        position: sticky;
        top: 0;
        align-self: flex-start;
        height: 100vh;
        height: 100dvh;
        overflow: hidden;
    }

    .contact-list {
        display: flex;
        flex: 1;
        flex-direction: column;
        min-height: 0;
    }

    .contact-list-header,
    .contact-list-search,
    .contact-list-add,
    .contact-list-logout {
        flex: none;
    }

    .contact-list-scroll {
        display: flex;
        flex: 1;
        flex-direction: column;
        min-height: 0;
        overflow-x: hidden;
        overflow-y: auto;
        overscroll-behavior: contain;
        scrollbar-color: var(--secondaryText) var(--surfaceBackground);
        scrollbar-width: thin;
    }

    .contact-list-scroll:focus-visible {
        outline: 2px solid var(--focusRing);
        outline-offset: -3px;
    }

    .contact-list-scroll::-webkit-scrollbar {
        width: 8px;
    }

    .contact-list-scroll::-webkit-scrollbar-track {
        background: var(--surfaceBackground);
    }

    .contact-list-scroll::-webkit-scrollbar-thumb {
        border: 2px solid var(--surfaceBackground);
        background: var(--secondaryText);
    }

    .contact-list-scroll::-webkit-scrollbar-thumb:hover {
        background: var(--primaryText);
    }

    .contact-list-items {
        flex: 0 0 auto;
    }

    .contact-list-scroll.is-full .contact-list-items {
        border-bottom-color: transparent;
    }

    .contact-list-spacer {
        flex: 1 0 0;
    }
}

@media (prefers-reduced-motion: reduce) {
    .contact-list-search::after,
    .contact-list-add::before,
    .btn-delete-contact {
        transition: none;
    }

    .delete-contact-dialog[open] {
        animation: none;
    }

    .dashboard-container[data-mobile-view="list"] .contact-list-section,
    .dashboard-container[data-mobile-view="detail"] .contact-details-view,
    .dashboard-container[data-mobile-view="edit"] .contact-edit-form,
    .dashboard-container[data-mobile-view="add"] .contact-details-form {
        animation: none !important;
    }
}

/* Tablet keeps the desktop master/detail layout, but gives more of the
   available width to the working panel and trims its outer whitespace. */
@media (min-width: 768px) and (max-width: 1023px) {
    .contact-list-section {
        flex-basis: 260px;
    }

    .contact-list-header h2 {
        font-size: 22px;
        white-space: nowrap;
    }

    .contact-workspace-panel {
        --panel-gutter: 20px;

        width: min(720px, calc(100% - 48px));
        margin: 75px auto 24px;
    }
}

@keyframes mobile-view-enter {
    from {
        opacity: 0;
        transform: translateX(8px);
    }

    to {
        opacity: 1;
        transform: translateX(0);
    }
}

@media (max-width: 767px) {
    .dashboard-container,
    .dashboard-inner {
        min-height: 100vh;
        min-height: 100dvh;
    }

    .dashboard-inner {
        display: block;
    }

    .contact-list-section {
        width: 100%;
        min-height: 100vh;
        min-height: 100dvh;
        border-right: 0;
        border-bottom: 1px solid var(--defaultBorder);
    }

    .contact-list-section::after {
        top: auto;
        right: 0;
        bottom: -3px;
        left: 0;
        width: auto;
        height: 1px;
    }

    .contact-list {
        display: flex;
        flex: 1;
        flex-direction: column;
    }

    .contact-list-scroll {
        display: flex;
        flex: 1;
        flex-direction: column;
    }

    .contact-list-spacer {
        flex: 1 0 0;
    }

    .contact-list-chevron {
        display: inline-block;
        flex: none;
        font-family: Arial, Helvetica, sans-serif;
        font-size: 28px;
        line-height: 1;
    }

    .btn-add-contact-text {
        display: inline;
    }

    .dashboard-container[data-mobile-view="list"] .contact-details,
    .dashboard-container[data-mobile-view="detail"] .contact-list-section,
    .dashboard-container[data-mobile-view="edit"] .contact-list-section,
    .dashboard-container[data-mobile-view="add"] .contact-list-section {
        display: none;
    }

    .dashboard-container[data-mobile-view="detail"] .contact-details-form,
    .dashboard-container[data-mobile-view="detail"] .contact-edit-form,
    .dashboard-container[data-mobile-view="edit"] .contact-details-view,
    .dashboard-container[data-mobile-view="edit"] .contact-details-form,
    .dashboard-container[data-mobile-view="add"] .contact-details-view,
    .dashboard-container[data-mobile-view="add"] .contact-edit-form {
        display: none;
    }

    .dashboard-container[data-mobile-view="add"] .contact-details-form {
        display: block;
    }

    .dashboard-container[data-mobile-view="list"] .contact-list-section,
    .dashboard-container[data-mobile-view="detail"] .contact-details-view,
    .dashboard-container[data-mobile-view="edit"] .contact-edit-form,
    .dashboard-container[data-mobile-view="add"] .contact-details-form {
        animation: mobile-view-enter 160ms ease-out;
    }

    .contact-details {
        min-height: 100vh;
        min-height: 100dvh;
    }

    .contact-workspace-panel {
        --panel-gutter: 16px;
        --panel-heading-y: 18px;
        --detail-row-y: 18px;
        --form-field-y: 11px;
        --panel-control-height: 50px;

        width: calc(100% - 32px);
        margin: 16px auto;
    }

    .contact-details-view {
        --contact-view-avatar-size: 56px;
    }

    .mobile-back-button {
        display: flex;
        align-items: center;
        gap: 8px;
        width: 100%;
        min-height: 44px;
        padding: 8px var(--panel-gutter);
        border: 0;
        border-bottom: 1px solid var(--defaultBorder);
        background-color: var(--surfaceBackground);
        color: var(--primaryText);
        font-family: "Cormorant Garamond", Georgia, serif;
        font-size: 16px;
        text-align: left;
    }

    .mobile-back-button:hover {
        background-color: var(--hoverBackground);
    }

    .mobile-back-button:focus-visible {
        outline: 2px solid var(--focusRing);
        outline-offset: -3px;
    }

    .contact-view-copy {
        width: 44px;
        height: 44px;
    }

    .contact-view-field-action {
        min-height: 44px;
    }

    .btn-contact-cancel {
        display: none;
    }

    .contact-view-identity h3 {
        font-size: 28px;
    }
}

@media (max-width: 480px) {
    .contact-list-search,
    .contact-list-items,
    .contact-list-add,
    .contact-list-logout {
        padding: 8px;
    }

    .contact-list-search.is-list-start::after,
    .contact-list-add.is-list-end::before {
        right: 8px;
        left: 8px;
    }

    .contact-list-items,
    .contact-list-item,
    .contact-view-identity,
    .contact-view-field {
        gap: 8px;
    }

    .contact-list-item {
        padding: 8px;
    }

    .contact-workspace-panel {
        --panel-gutter: 12px;
        --panel-heading-y: 16px;
        --detail-row-y: 16px;
        --form-field-y: 10px;
        --panel-control-height: 48px;

        width: calc(100% - 16px);
        margin: 8px auto;
    }

    .delete-contact-dialog {
        width: calc(100% - 16px);
        max-height: calc(100vh - 16px);
        max-height: calc(100dvh - 16px);
    }

    .delete-dialog-content {
        padding: 20px 16px 14px;
    }

    .delete-dialog-actions {
        grid-template-columns: 1fr;
        gap: 8px;
        padding: 0 16px 16px;
    }

    .contact-details-view {
        --contact-view-avatar-size: 48px;
    }

    .contact-panel-heading {
        gap: 10px;
    }

    .contact-view-avatar {
        font-size: 19px;
    }

    .contact-view-identity h3 {
        font-size: 24px;
    }

    .contact-view-field-action {
        width: 44px;
        padding: 0;
    }

    .contact-view-field-action-text {
        display: none;
    }
}

/* Admin page. Every rule is scoped to .admin-page, the class on admin.html's
   body, so none of it touches the other pages. The first three rules undo
   site-wide styles from above that admin doesn't use. */
body.admin-page {
    font-family: sans-serif;
    background-color: revert;
    color: revert;
}

.admin-page *,
.admin-page *::before,
.admin-page *::after {
    box-sizing: revert;
}

.admin-page :is(a, button, input, label, select, summary, textarea) {
    cursor: revert;
}

.admin-page nav {
    display: flex;
    align-items: center;
    padding: 0 20px 0 12px;
    background: #fff;
    border-bottom: 1px solid #ccc;
}

/* The active tab gets a dark underline. */
.admin-page .tab {
    align-self: stretch;
    margin-bottom: -1px;
    padding: 14px 20px;
    border: none;
    border-bottom: 2px solid transparent;
    background: none;
    color: #6b6b6b;
    font: inherit;
    cursor: pointer;
}

.admin-page .tab:hover {
    color: #333;
    background: #f2f2f2;
}

.admin-page .tab.active {
    background: #e8e8e8;
    color: #333;
    font-weight: bold;
    border-bottom-color: #333;
}

.admin-page .logout-button {
    width: auto;
    margin-left: auto;
}

.admin-page main {
    padding: 20px;
}

.admin-page .table-scroll {
    overflow-x: auto;
}

.admin-page table {
    width: 100%;
    border-collapse: collapse;
    border: 1px solid #ccc;
}

/* Lines around the table and between rows, none between columns. Cells don't
   wrap, so on a narrow screen the table scrolls sideways. */
.admin-page th,
.admin-page td {
    padding: 8px;
    border-bottom: 1px solid #ccc;
    text-align: left;
    white-space: nowrap;
}

/* The total under each table. */
.admin-page .table-count {
    margin: 8px 0 0;
    color: #6b6b6b;
    font-size: 14px;
    text-align: right;
}

/* Sortable column headers. The arrow marks the sorted column. */
.admin-page .sort-button {
    padding: 0;
    border: none;
    background: none;
    color: inherit;
    font: inherit;
    cursor: pointer;
}

.admin-page .sort-button:focus-visible {
    outline: 2px solid #333;
    outline-offset: 2px;
}

.admin-page th[aria-sort="ascending"] .sort-button::after,
.admin-page th[aria-sort="descending"] .sort-button::after {
    margin-left: 4px;
    color: #6b6b6b;
    font-size: 12px;
}

.admin-page th[aria-sort="ascending"] .sort-button::after {
    content: "\25B2";
}

.admin-page th[aria-sort="descending"] .sort-button::after {
    content: "\25BC";
}

/* Empty values show as "----". */
.admin-page td.empty-cell {
    color: #999;
}

/* Disabled users are greyed out, but their Actions button isn't. */
.admin-page tr.is-disabled td {
    color: #6b6b6b;
    background: #f2f2f2;
}

/* The Actions menu. js/code.js places it under its button. */
.admin-page .actions-menu {
    position: fixed;
    inset: auto;
    margin: 0;
    padding: 4px 0;
    list-style: none;
    background: #fff;
    border: 1px solid #ccc;
}

.admin-page .actions-menu button {
    display: block;
    width: 100%;
    padding: 6px 12px;
    border: none;
    background: none;
    text-align: left;
    white-space: nowrap;
    cursor: pointer;
}

.admin-page .actions-menu button:hover {
    background: #eee;
}

.admin-page .toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
}

/* Light buttons: Add user, Actions, and the dialog buttons. */
.admin-page .btn {
    padding: 7px 14px;
    border: 1px solid #ccc;
    border-radius: 4px;
    background: #fff;
    color: #333;
    font: inherit;
    cursor: pointer;
}

.admin-page .btn:hover {
    background: #f2f2f2;
    border-color: #999;
}

.admin-page .btn:focus-visible {
    outline: 2px solid #333;
    outline-offset: 2px;
}

.admin-page .btn:disabled {
    background: #fff;
    border-color: #ccc;
    opacity: 0.6;
    cursor: default;
}

/* The dark button for a dialog's main action. */
.admin-page .btn-primary,
.admin-page .btn-primary:disabled {
    width: auto;
    border-color: #333;
    background: #333;
    color: #fff;
}

.admin-page .btn-primary:hover {
    border-color: #555;
    background: #555;
}

.admin-page .actions-toggle {
    padding: 4px 10px;
    font-size: 14px;
    white-space: nowrap;
}

.admin-page .text-input {
    padding: 7px 10px;
    border: 1px solid #ccc;
    border-radius: 4px;
    font: inherit;
}

/* Keeps a lone search box on the right. */
.admin-page .toolbar-end {
    justify-content: flex-end;
}

/* The "Search in" dropdown. Selects render 2px taller than inputs, so it
   gets 1px less padding top and bottom. */
.admin-page .search-in {
    width: auto;
    padding-top: 6px;
    padding-bottom: 6px;
}

/* The search box and dropdown joined into one control with a single shared
   border. */
.admin-page .search-group {
    display: flex;
    max-width: 100%;
}

.admin-page .search-group .search-field {
    flex: 0 1 240px;
    min-width: 0;
}

.admin-page .search-group .search-field .text-input {
    border-radius: 4px 0 0 4px;
}

.admin-page .search-group .search-in {
    flex: none;
    margin-left: -1px;
    border-radius: 0 4px 4px 0;
}

/* Raise the focused half so its focus ring isn't hidden. */
.admin-page .search-group .text-input:focus {
    position: relative;
    z-index: 1;
}

/* Keep the × above the focused box. */
.admin-page .search-group .search-clear {
    z-index: 2;
}

.admin-page .search-field {
    position: relative;
    width: 240px;
    max-width: 100%;
}

.admin-page .search-field .text-input {
    box-sizing: border-box;
    width: 100%;
    padding-right: 32px;
}

/* Hide the browser's clear button; we use our own ×. */
.admin-page .search-field .text-input::-webkit-search-cancel-button {
    -webkit-appearance: none;
    appearance: none;
}

.admin-page .search-clear {
    position: absolute;
    top: 50%;
    right: 6px;
    transform: translateY(-50%);
}

.admin-page .search-field .text-input:placeholder-shown + .search-clear {
    display: none;
}

/* The Reset password and Add user dialogs. */
.admin-page .dialog {
    width: 360px;
    max-width: calc(100% - 32px);
    padding: 20px;
    border: 1px solid #ccc;
    border-radius: 4px;
}

.admin-page #add-user-dialog {
    width: 440px;
}

.admin-page .dialog::backdrop {
    background: rgba(0, 0, 0, 0.3);
}

/* Negative margins cancel the dialog's padding so the header runs edge to
   edge. */
.admin-page .dialog-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin: -20px -20px 16px;
    padding: 14px 20px;
    border-bottom: 1px solid #ccc;
}

.admin-page .dialog-header h3 {
    margin: 0;
    font-size: 18px;
}

.admin-page .dialog label {
    display: block;
    margin-bottom: 16px;
}

.admin-page .dialog .text-input {
    display: block;
    box-sizing: border-box;
    width: 100%;
    margin-top: 6px;
}

/* Read-only fields look inactive. */
.admin-page .dialog .text-input[readonly] {
    background: #f2f2f2;
    color: #6b6b6b;
}

/* Two fields side by side, like first and last name. */
.admin-page .field-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.admin-page .dialog-actions {
    display: flex;
    margin-top: 20px;
    gap: 8px;
}

.admin-page .status-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
    padding: 10px 12px;
    background: #f3f6fa;
    border: 1px solid #c9d3e0;
    border-radius: 4px;
}

.admin-page .status-card[hidden] {
    display: none;
}

.admin-page .status-card p {
    margin: 0;
}

/* The × close button on the status card and dialogs. */
.admin-page .close-button {
    padding: 0 4px;
    border: none;
    background: none;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
}
