/*
 * The shell: a rail of areas, and a column of content.
 *
 * The rail is always the same targets in the same places, so navigating stops
 * being reading. The strip at the top of the column names the screens inside
 * whichever area you are in, and only appears when there is more than one.
 */

.ff-shell {
    min-height: 100dvh;
}

.ff-rail {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: 76px;
    z-index: 30;
    background: var(--ff-rail);
    border-right: 1px solid var(--ff-line-soft);
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 1rem .5rem;
    gap: .75rem;
}

/*
 * The mark is the logo, standing on the rail's own dark rather than on a tile.
 * It was a lime chip with the letters FF set in it, which is what you draw
 * before you have a logo; now that we have one, a lime chip under a lime mark
 * would only hide it.
 *
 * It sits narrower than the area tiles below it. The mark is not a target you
 * hunt for — it is the one thing on the rail you already know the position of —
 * so it does not need to be the largest thing there, and at full width it read
 * as a heading over the areas rather than as the corner of the room.
 *
 * The box keeps its 2.5rem height whatever the mark measures, so shrinking the
 * logo does not move every icon under it.
 */
.ff-rail-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.2rem;
    height: 2.5rem;
    text-decoration: none;
    flex: 0 0 auto;
}

.ff-rail-mark img {
    display: block;
    width: 100%;
    height: auto;
}

.ff-rail-items {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .25rem;
    margin-top: .5rem;
    flex: 1 1 auto;
}

.ff-rail-item {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 44px of reach, and square so the icon sits dead centre. */
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--ff-r-control);
    color: var(--ff-faint);
    font-size: 1.15rem;
    text-decoration: none;
    transition: color .2s var(--ff-ease), background-color .2s var(--ff-ease);
}

.ff-rail-item:hover {
    color: var(--ff-text);
    background: var(--ff-line-soft);
}

.ff-rail-item.is-current {
    color: var(--ff-on-accent);
    background: var(--ff-accent);
}

/*
 * An icon alone is a guess until you have learned it, so the name arrives on
 * hover and on keyboard focus rather than never.
 */
.ff-rail-label {
    position: absolute;
    left: calc(100% + .5rem);
    white-space: nowrap;
    background: var(--ff-deep);
    color: var(--ff-text);
    border: 1px solid var(--ff-line);
    border-radius: var(--ff-r-control);
    padding: .3rem .6rem;
    font-size: var(--ff-t-small);
    font-weight: 500;
    opacity: 0;
    transform: translateX(-4px);
    pointer-events: none;
    transition: opacity .18s var(--ff-ease), transform .18s var(--ff-ease);
    box-shadow: var(--ff-shadow);
}

.ff-rail-item:hover .ff-rail-label,
.ff-rail-item:focus-visible .ff-rail-label {
    opacity: 1;
    transform: none;
}

.ff-rail-you {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: var(--ff-r-pill);
    background: var(--ff-line-soft);
    color: var(--ff-dim);
    font-weight: 600;
    font-size: var(--ff-t-small);
    text-decoration: none;
    flex: 0 0 auto;
}

.ff-rail-you:hover { color: var(--ff-text); background: var(--ff-line); }

.ff-column {
    margin-left: 76px;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
}

/* ── The strip of screens inside an area ──────────────────────────────────── */

/*
 * Ten screens do not fit on a 390px phone, so the strip scrolls. Two things had
 * to be true for that to be honest rather than hidden.
 *
 * The screen you are on has to be on screen. It was not: on a phone `Reconcile`
 * sat at x=475 and `Library` at x=794 inside a 390px window with `scrollLeft` at
 * 0, so the strip showed the first three screens on every single page and the
 * person had no way to tell which one they were looking at.
 *
 * And the strip has to look like it continues. The edge affordances below say
 * so — but only when there really is more, and only on the side there is more
 * on. That distinction is the whole lesson of the table fade that ate the last
 * digit of every figure: CSS cannot ask whether a box is overflowing, so it
 * guesses and is usually wrong. Here JavaScript measures and sets the class,
 * which is also why an arrow is safe: it only ever appears over a nav label
 * that genuinely runs off the edge, and never over a number.
 */
.ff-strip-wrap {
    position: relative;
}

.ff-strip-wrap::before,
.ff-strip-wrap::after {
    position: absolute;
    top: 0;
    bottom: .25rem;
    width: 2.5rem;
    pointer-events: none;
    opacity: 0;
    z-index: 1;
    transition: opacity .18s var(--ff-ease);
    /* The arrow, not the fade, is what actually says "more this way". A fade
       alone does nothing when the last visible screen happens to end short of
       the edge, which on /net-worth/ it does: four names, a gap, and a strip
       that reads as the whole list when six more are off to the right. */
    display: flex;
    align-items: center;
    font-family: bootstrap-icons;
    font-size: .8rem;
    color: var(--ff-faint);
}

.ff-strip-wrap::before {
    left: 0;
    justify-content: flex-start;
    padding-left: .25rem;
    background: linear-gradient(to right, var(--ff-bg) 55%, transparent);
    content: "\f284";   /* chevron-left */
}

.ff-strip-wrap::after {
    right: 0;
    justify-content: flex-end;
    padding-right: .25rem;
    background: linear-gradient(to left, var(--ff-bg) 55%, transparent);
    content: "\f285";   /* chevron-right */
}

.ff-strip-wrap.has-more-before::before,
.ff-strip-wrap.has-more-after::after { opacity: 1; }

.ff-strip {
    display: flex;
    gap: .15rem;
    padding: .75rem 1.25rem .25rem;
    overflow-x: auto;
    /* Deliberately not `scroll-behavior: smooth`. The one programmatic scroll
       here is the jump to the current screen on load, and animating that means
       the nav slides every single time a page opens — motion on every render is
       wallpaper within a day. It arrives already in the right place. */
    scrollbar-width: none;
}

.ff-strip::-webkit-scrollbar { display: none; }

.ff-strip a {
    color: var(--ff-faint);
    text-decoration: none;
    padding: .35rem .75rem;
    border-radius: var(--ff-r-pill);
    min-height: 2.25rem;
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
    font-size: var(--ff-t-small);
    transition: color .2s var(--ff-ease), background-color .2s var(--ff-ease);
}

.ff-strip a:hover { color: var(--ff-text); background: var(--ff-line-soft); }

.ff-strip a.is-current {
    color: var(--ff-text);
    background: var(--ff-line-soft);
    font-weight: 600;
    box-shadow: inset 0 0 0 1px var(--ff-line);
}

/* ── Phone: the rail becomes a bottom bar ─────────────────────────────────── */

/*
 * The top of a phone screen is the hardest place on the device to reach and the
 * bottom is the easiest, so the areas move to the thumb.
 */
@media (max-width: 991.98px) {
    .ff-rail {
        top: auto;
        right: 0;
        width: auto;
        height: auto;
        flex-direction: row;
        justify-content: space-around;
        align-items: center;
        border-right: 0;
        border-top: 1px solid var(--ff-line-soft);
        padding: .35rem .5rem calc(.35rem + env(safe-area-inset-bottom));
        gap: 0;
    }

    /* The mark and the avatar are not destinations worth a thumb on a phone. */
    .ff-rail-mark,
    .ff-rail-you { display: none; }

    .ff-rail-items {
        flex-direction: row;
        justify-content: space-around;
        width: 100%;
        margin-top: 0;
        gap: 0;
    }

    .ff-rail-item {
        width: 100%;
        max-width: 4.5rem;
        /* Icon over name, the way every phone tab bar has worked for a decade. */
        flex-direction: column;
        justify-content: center;
        gap: .1rem;
        height: auto;
        min-height: 3.25rem;
        padding: .3rem 0;
        font-size: 1.05rem;
    }

    /*
     * On a touch screen there is no hover, so the tooltip version of this label
     * was a name nobody could ever read: six identical-weight glyphs for Money,
     * Mine, Attendance, Applications, Appointments and Docs, two of which begin
     * with the same three letters. It is a permanent caption here instead.
     */
    .ff-rail-label {
        display: block;
        position: static;
        opacity: 1;
        transform: none;
        background: none;
        border: 0;
        box-shadow: none;
        padding: 0;
        color: inherit;
        /* Twelve characters into a sixth of 390px. `Appointments` is the one
           that decides the size, and it has to be readable next to
           `Applications` rather than clipped to `Appointmen…`, because those
           two are the pair a person can actually confuse. */
        font-size: .5938rem;
        font-weight: 500;
        line-height: 1.1;
        letter-spacing: -.01em;
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* The current area is a filled lozenge on a desktop rail. Filled behind a
       word as well as an icon is a lot of lime at the bottom of a phone, so the
       tab keeps the accent for the mark and gives the background back. */
    .ff-rail-item.is-current {
        background: transparent;
        color: var(--ff-accent);
    }

    .ff-column {
        margin-left: 0;
        /* Clear of the bar, including the home indicator on an iPhone. */
        padding-bottom: calc(4.75rem + env(safe-area-inset-bottom));
    }

    .ff-strip {
        padding: .6rem .875rem .25rem;
    }
}

/* ── Date fields ──────────────────────────────────────────────────────────── */

/*
 * There are at least eleven `<input type="date">` in this app — the balance
 * sheet, the trial balance, accounts, all four record-money tabs, both ends of
 * the transaction filter, a target's due date, My Work's day, the reconcile
 * modal and the chart settings — and every one of them was rendering as the
 * browser's stock control: a pale box with a system font, sitting next to pill
 * buttons in the house type.
 *
 * Bound to the element rather than to a class on purpose. A class means eleven
 * template edits in five apps and a twelfth input somebody adds next month that
 * nobody remembers to mark. `.ff-date` is here as well for anything that wants
 * the same shape without being a date.
 *
 * `input[type="date"]` outranks `.form-control` on specificity, so the Bootstrap
 * treatment underneath stays where it is and this sits on top of it.
 *
 * What CSS cannot do, so nobody goes looking: the field order and separators are
 * the browser's locale, not the document's. `08/16/2026` on a Chilean company's
 * screen is Chrome's UI language, and no stylesheet, `lang` attribute or Django
 * setting changes it. The value posted is always ISO, so this is presentation
 * only — but it is presentation we do not control.
 */
input[type="date"],
.ff-date {
    /* iOS Safari renders a date field as a bare line of text without this. */
    -webkit-appearance: none;
    appearance: none;
    /* `.ff-btn`'s height and border, because a date field stands beside the
       preset buttons on /accounts/, /balance-sheet/ and /trial-balance/ and was
       three pixels shorter than all of them. Not `.ff-btn`'s pill radius
       though: eight of the eleven stand in a *form*, next to a text field and
       two selects, and a full-width pill in a column of rounded rectangles
       reads as a different kind of control rather than as the same one. */
    min-height: 2.75rem;
    padding: 0 .95rem;
    border: 1px solid var(--ff-line);
    border-radius: var(--ff-r-control);
    background-color: var(--ff-deep);
    color: var(--ff-text);
    /* A date is a run of figures compared against another run of figures. */
    font-family: var(--ff-mono);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    font-size: var(--ff-t-small);
    line-height: 1;
    transition: border-color .2s var(--ff-ease), box-shadow .2s var(--ff-ease);
}

input[type="date"]:hover { border-color: var(--ff-faint); }

input[type="date"]:focus,
input[type="date"]:focus-visible {
    background-color: var(--ff-deep);
    border-color: var(--ff-accent-line);
    color: var(--ff-text);
    box-shadow: 0 0 0 3px var(--ff-accent-soft);
    /* The ring above is the focus indicator; the global outline on top of a
       pill would draw a rectangle around a rounded field. */
    outline: none;
}

input[type="date"]:disabled {
    color: var(--ff-faint);
    background-color: var(--ff-surface);
}

/* WebKit renders the picker button as a near-black glyph, which on a surface
   this dark is a control you can only find by guessing where it is. */
input[type="date"]::-webkit-calendar-picker-indicator {
    filter: invert(1);
    opacity: .5;
    cursor: pointer;
    transition: opacity .18s var(--ff-ease);
}

input[type="date"]:hover::-webkit-calendar-picker-indicator,
input[type="date"]:focus::-webkit-calendar-picker-indicator { opacity: 1; }

input[type="date"]::-webkit-datetime-edit { padding: 0; }
input[type="date"]::-webkit-datetime-edit-fields-wrapper { padding: 0; }
input[type="date"]::-webkit-datetime-edit-text { color: var(--ff-faint); padding: 0 .1em; }

/* Not attempted, having been tried: the highlight on the segment you are typing
   in is the system's, and Chrome ignores `::selection` and the per-field
   pseudo-elements for it. It stays stock blue. Along with the field order, that
   is the second and last thing about this control CSS does not reach. */

/* The unfilled segments read as placeholder text, not as content. */
input[type="date"]::-webkit-datetime-edit-year-field:not([aria-valuenow]),
input[type="date"]::-webkit-datetime-edit-month-field:not([aria-valuenow]),
input[type="date"]::-webkit-datetime-edit-day-field:not([aria-valuenow]) {
    color: var(--ff-faint);
}

/*
 * The week grouping and day rows that used to live here were My Work's, and My
 * Work now carries its own `work-*` styles in payroll.css. Left in place they
 * were ninety lines nobody could safely change, because nothing said which
 * screen they belonged to.
 */

.cursor-pointer, .cursor-pointer > * {
    cursor: pointer;
}

.mx-05 {
    margin-right: .125rem !important;
    margin-left: .125rem !important;
}

.table-responsive .dropdown,
.table-responsive .btn-group,
.table-responsive .btn-group-vertical {
    position: static;
}

.spinner-htmx {
    display: none !important;
}
.htmx-request > .spinner-htmx {
    display: inline-block !important;
}
.htmx-request > .htmx-content {
    display: none !important;
}

.photo-thumbnail {
    width: 5rem;
    height: 5rem;
    object-fit: cover;
    border-radius: 50%;
}

.sort-by-ascending, .sort-by-descending {
    cursor: pointer;
    &:hover {
        opacity: .5;
    }
}

.table a {
    text-decoration: none;
}

.hidden-link {
    text-decoration: none;
    color: inherit;
    &:hover {
        opacity: .8;
    }
}

.htmx-input {
    background-color: #1d2024;
    padding: 0 0 .2rem 0;
    cursor: pointer;
    color: #fff;
    &:hover {
        background-color: #2f3037;
    }
    &:focus {
        cursor: auto;
    }
}
.htmx-input[type='number']::-webkit-inner-spin-button,
.htmx-input[type='number']::-webkit-outer-spin-button {
    margin-left: -0.85rem;
}
.htmx-input[type=''] {

}
.htmx-input-lg {
    font-size: 2rem;
    font-weight: bold;
    min-width: 5rem;
}

.clickable {
    cursor: pointer;
    &:hover {
        opacity: .8;
    }
}

.x-small {
    font-size: .7rem;
}
/* ── Applications: choosing a hiring round ─────────────────────────────────── */

/* A whole row that is a link. The row carries its own hover; this only stops
 * the browser painting the title blue and underlining it. */
.apply-round,
.apply-round:hover {
    text-decoration: none;
    color: inherit;
}

.apply-round .ff-list-title { transition: color .18s var(--ff-ease); }
.apply-round:hover .ff-list-title { color: var(--ff-accent); }

/* Nothing waiting is not good news or bad news, so it gets no semantic colour. */
.apply-chip {
    background: rgba(255, 255, 255, .05);
    color: var(--ff-dim);
}

/*
 * The avatar is a destination like any other — it goes to the admin — so it
 * shows as current when that is where you are. Same treatment the area icons
 * get, for the same reason: a navigation that cannot say where you are is a
 * navigation you stop trusting.
 */
.ff-rail-you.is-current {
    color: var(--ff-on-accent);
    background: var(--ff-accent);
}

.ff-rail-you.is-current:hover {
    color: var(--ff-on-accent);
    background: var(--ff-accent);
}
