/* ============================================================================
   Hagzi — publishing a property listing
   ============================================================================

   Two screens use this file: the Publish row at the foot of Add Listing, and
   the listing table on My Listings. They are one feature and they share a
   button, so they share a stylesheet.

   It is a new file on purpose. property.css, property-pages.css and
   property-account.css are all being worked on in parallel, so nothing here is
   added to them. Every selector is prefixed .hzpub-, which means this file
   cannot win or lose a specificity argument with any of them — there is nothing
   to argue about.

   THE BUTTON

   Copied from .hzp-btn as it is actually written in
   public/themes/property/property-pages.css (read, not assumed):

       height 40px · radius 6px (--hzp-radius-sm) · 14px/500
       secondary  #ffffff on a 1px #d6dae1 border (--hzp-line-strong),
                  ink #12141a (--hz-ink)
       primary    #0745D9 filled (--hagzi-primary), white text,
                  #0638B0 on hover (--hagzi-primary-dark)

   Each token is read with the literal as a fallback, so this is right whether
   or not the file that declares it has loaded first. Add Listing's own .hzf-btn
   is 42px tall at weight 600; the Publish row does not use it, because a 40px
   Publish beside a 42px Clear the form is the kind of two-pixel mismatch that
   reads as a mistake.
   ========================================================================= */

.hzpub-row,
.hzpub-table,
.hzpub-head--edit,
.hzpub-danger,
.hzpub-flash,
/* The toolbar and the dialogue read the same tokens. Added to this list rather
   than redeclared, so there is one place the accent lives. */
.hzpub-filters,
.hzdel {
    --hzpub-accent: var(--hagzi-primary, #0745D9);
    --hzpub-accent-dark: var(--hagzi-primary-dark, #0638B0);
    --hzpub-ink: var(--hz-ink, #12141a);
    --hzpub-muted: #6b7280;
    --hzpub-line: var(--hz-line, #e7e9ee);
    --hzpub-line-strong: #d6dae1;
    --hzpub-radius: 6px;
}

/* ------------------------------------------------------------------ button --- */

.hzpub-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    height: 40px;
    padding: 0 16px;
    border: 1px solid var(--hzpub-line-strong);
    border-radius: var(--hzpub-radius);
    background: #ffffff;
    color: var(--hzpub-ink);
    font-family: inherit;
    font-size: 14px;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
}

/* Outline icons, like every other icon in this theme. Never `fill`: an earlier
   `fill: #ffffff` on the accent variant of .hzp-btn filled every closed path
   and turned a calendar glyph into a white block. */
.hzpub-btn svg {
    flex: none;
    width: 16px;
    height: 16px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.hzpub-btn--primary {
    border-color: var(--hzpub-accent);
    background: var(--hzpub-accent);
    color: #ffffff;
}

.hzpub-btn--primary:hover {
    border-color: var(--hzpub-accent-dark);
    background: var(--hzpub-accent-dark);
}

/* Clear the form. A real control, so it gets real hover feedback, but it stays
   quiet: it is the way out of the form, not a second way forward. */
.hzpub-btn--quiet {
    border-color: transparent;
    background: transparent;
    color: var(--hzpub-muted);
    text-decoration: underline;
}

.hzpub-btn--quiet:hover {
    color: var(--hzpub-ink);
}

.hzpub-btn:focus-visible {
    outline: 2px solid var(--hzpub-accent);
    outline-offset: 2px;
}

/* Mid-publish. Still legible — a disabled control that fades to nothing looks
   broken rather than busy — and the cursor says why it is not responding. */
.hzpub-btn[disabled] {
    opacity: .72;
    cursor: progress;
}

/* --------------------------------------------------------------- the row --- */

.hzpub-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
}

/* What came back from the server. Empty until there is something to say, and
   it takes no space while empty, so the row does not shift when it fills. */
.hzpub-status {
    margin: 0;
    font-size: 13px;
    line-height: 1.5;
    color: var(--hzpub-muted);
}

.hzpub-status:empty {
    display: none;
}

/* The phone number under the actions, on its own line rather than trailing the
   sentence about review — two separate things to know. */
.hzpub-note__line {
    display: block;
    margin-top: 4px;
}

@media (max-width: 599px) {
    /*
        Full width and Publish first. Two buttons side by side at 390px leave
        Publish too narrow to read comfortably, and `Clear the form` should
        never be the easier of the two to hit.
    */
    .hzpub-row {
        gap: 10px;
    }

    .hzpub-row .hzpub-btn {
        width: 100%;
    }

    .hzpub-status {
        order: 3;
    }
}


/* ======================================================================
   My Listings — the listing table  (.hzpub-table)
   ======================================================================

   Built to the same structure as the car channel's My Listings row, in the
   property design language.

   WHY MATCH THE CAR SCREEN AT ALL

   The card this replaces was a card: a photograph beside a stack of prose, with
   the specification run together on one line and a full sentence of body copy
   underneath. It held the same facts but it made the reader hunt for each one,
   and with more than one listing nothing lined up with anything.

   The car screen solves that by not being cards. It is a table — one grid,
   declared once, used by a header row and by every listing — so price sits
   under Price on every row and a seller reads down a column instead of across a
   paragraph. Its geometry is copied here exactly, from
   packages/Webkul/Shop/src/Resources/views/customers/my-account/partials/
   listings-styles.blade.php (read, not guessed):

       columns   minmax(0,1fr) 112px 132px 88px 158px
       gap       14px            padding      14px 18px
       header    11px/500, .03em, uppercase, on #fcfcfd, 11px block padding
       thumb     84 x 63, 1px border, 6px radius
       title     13.5px/500, line-height 1.35, clamped to 2 lines
       spec      11.5px, one line, ellipsis
       price     13.5px/700, with an 11px qualifier under it
       badge     999px pill, 6px dot, 11.5px/500, padding 3px 10px 3px 8px
       divider   1px between rows, and hover #fcfcfd

   WHAT IS NOT COPIED

   The palette. The car screen hovers its title to `--acct-red` and fills its
   primary button red; here both are #0745D9, the property accent, and the
   button is the .hzp-btn treatment already declared above rather than
   `.acct-btn`. None of the `.acct-` custom properties are read — they are
   declared on the car theme's account shell, which this page does not load, so
   every value is written out or taken from a --hzpub- token.

   The columns are also renamed. `.hzpub-row` above is the Publish row at the
   foot of Add Listing and was here first, so a listing row is `.hzpub-listing`
   rather than fighting it for the name.
   ==================================================================== */

.hzpub-table {
    /*
        One grid, declared once and used by the header and every row, so a
        column cannot drift out of line with its heading.

        Five columns, matching the car screen: Property, Price, Status, Listed
        on, Actions. There is no Views and no Enquiries column, because nothing
        on this installation counts either and a column of zeroes would be a
        claim about traffic that no data supports.
    */
    --hzpub-columns: minmax(0, 1fr) 112px 132px 88px 158px;

    min-width: 0;
}

.hzpub-head,
.hzpub-listing {
    display: grid;
    align-items: start;
    gap: 14px;
    grid-template-columns: var(--hzpub-columns);
    padding: 14px 18px;
}

.hzpub-head {
    padding-top: 11px;
    padding-bottom: 11px;
    border-bottom: 1px solid var(--hzpub-line);
    background: #fcfcfd;
    color: var(--hzpub-muted);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .03em;
    text-transform: uppercase;
}

/* A divider between listings, not around each one. Two adjacent rows share one
   line, which is what makes the set read as a table rather than as a stack of
   boxes. */
.hzpub-listing + .hzpub-listing {
    border-top: 1px solid var(--hzpub-line);
}

.hzpub-listing:hover {
    background: #fcfcfd;
}

/* ---------------------------------------------------------- the property --- */

.hzpub-listing__property {
    display: flex;
    min-width: 0;
    gap: 13px;
}

.hzpub-listing__thumb {
    position: relative;
    overflow: hidden;
    width: 84px;
    height: 63px;
    flex-shrink: 0;
    border: 1px solid var(--hzpub-line);
    border-radius: var(--hzpub-radius);
    background: #f4f5f8;
}

.hzpub-listing__thumb img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* No photographs. Says so in words rather than showing a broken frame or a
   stock photograph of somebody else's building. */
.hzpub-listing__thumb > span {
    display: grid;
    width: 100%;
    height: 100%;
    place-items: center;
    padding: 4px;
    font-size: 10px;
    line-height: 1.3;
    text-align: center;
    color: #9ca3af;
}

.hzpub-listing__text {
    display: grid;
    min-width: 0;
    gap: 3px;
    padding-top: 2px;
}

/*
    The title is the one thing on the row a seller scans for, so it wraps to a
    second line rather than being cut at the first. Everything under it is a
    detail and takes the ellipsis instead.
*/
.hzpub-listing__title {
    display: -webkit-box;
    overflow: hidden;
    color: var(--hzpub-ink);
    font-size: 13.5px;
    font-weight: 500;
    line-height: 1.35;
    text-decoration: none;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
}

/* Property purple, where the car screen uses its red. */
a.hzpub-listing__title:hover {
    color: var(--hzpub-accent);
}

.hzpub-listing__spec,
.hzpub-listing__ref {
    overflow: hidden;
    color: var(--hzpub-muted);
    font-size: 11.5px;
    line-height: 1.45;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.hzpub-listing__ref {
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    letter-spacing: .01em;
}

/* ------------------------------------------------------------- the price --- */

.hzpub-listing__price {
    color: var(--hzpub-ink);
    font-size: 13.5px;
    font-weight: 700;
}

/* Sale price, or the rent period. A bare figure in a column that mixes monthly
   rents with purchase prices is not a price. */
.hzpub-listing__terms {
    margin-top: 2px;
    color: var(--hzpub-muted);
    font-size: 11px;
    font-weight: 400;
}

.hzpub-listing__date {
    color: #4a5160;
    font-size: 12px;
}

/* ------------------------------------------------------------ the status --- */

.hzpub-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px 3px 8px;
    border: 1px solid transparent;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 500;
    /* Stated in pixels, not inherited and not a ratio. The property theme sets a
       1.5 body line-height and the car screen's account shell does not, which on
       its own made this badge four pixels taller than the one it is meant to
       match. A ratio got it to within a quarter of a pixel; 13px lands both
       badges on exactly 21. */
    line-height: 13px;
    white-space: nowrap;
}

.hzpub-badge::before {
    width: 6px;
    height: 6px;
    border-radius: 999px;
    background: currentColor;
    content: "";
}

/*
    Green means one thing on this screen: a member of the public can see this
    listing right now. It is set from `status_tone`, which is only ever `live`
    when the row has both a product and a url_key — so the colour cannot claim
    something the data does not support.
*/
.hzpub-badge--live {
    border-color: #a7f3d0;
    background: #ecfdf5;
    color: #047857;
}

.hzpub-badge--muted {
    border-color: var(--hzpub-line-strong);
    background: #f6f7f9;
    color: #4b5563;
}

/* The short qualifier under the badge — "On the site and in search". Four words
   in the Status column, where the card this replaces put a whole sentence
   across the full width of the panel. */
.hzpub-listing__qualifier {
    margin: 5px 0 0;
    color: var(--hzpub-muted);
    font-size: 11px;
    line-height: 1.4;
}

/* ----------------------------------------------------------- the actions --- */

.hzpub-listing__actions {
    display: grid;
    justify-items: stretch;
    gap: 6px;
}

/*
    The small button. The .hzpub-btn above is the 40px Publish control; inside a
    table row that is too tall, so this is the same button at the car screen's
    row scale — 12px text, 7px/10px padding, 13px icon.
*/
.hzpub-btn--sm {
    gap: 6px;
    height: auto;
    padding: 7px 10px;
    font-size: 12px;
    /* 7 + 18 + 7 + 2 borders = 34px, the height of the car screen's row button.
       The 40px .hzpub-btn above sets `line-height: 1`, which would make this 29. */
    line-height: 18px;
}

.hzpub-btn--sm svg {
    width: 13px;
    height: 13px;
}

/* ------------------------------------------------------------ narrow --- */

/* The date column folds away first; it is the least load bearing. */
@media (max-width: 1279.98px) {
    .hzpub-table {
        --hzpub-columns: minmax(0, 1fr) 120px 140px 158px;
    }

    .hzpub-head span:nth-child(4),
    .hzpub-listing__date {
        display: none;
    }
}

@media (max-width: 1023.98px) {
    .hzpub-table {
        --hzpub-columns: minmax(0, 1fr) 148px;
    }

    .hzpub-head span:nth-child(2),
    .hzpub-head span:nth-child(3) {
        display: none;
    }

    .hzpub-head span:last-child {
        text-align: end;
    }

    /*
        Price and status move under the title, indented past the thumbnail so
        they read as facts about the property rather than as orphaned columns.
        Placed explicitly: three stacked cells beside one block of actions is
        not an arrangement auto-placement arrives at.

        98px is the 84px thumbnail plus its 13px gap, rounded up by one.
    */
    .hzpub-listing__property {
        grid-area: 1 / 1;
    }

    .hzpub-listing__price {
        grid-area: 2 / 1;
        margin-inline-start: 98px;
    }

    .hzpub-listing__status {
        grid-area: 3 / 1;
        margin-inline-start: 98px;
    }

    .hzpub-listing__actions {
        grid-area: 1 / 2 / span 3 / 3;
        align-content: start;
    }
}

@media (max-width: 767.98px) {
    .hzpub-table {
        --hzpub-columns: minmax(0, 1fr);
    }

    /* Nothing left to head. */
    .hzpub-head {
        display: none;
    }

    .hzpub-listing {
        gap: 12px;
        padding: 15px;
    }

    .hzpub-listing__property,
    .hzpub-listing__price,
    .hzpub-listing__status,
    .hzpub-listing__actions {
        grid-area: auto;
        margin-inline-start: 0;
    }
}

@media (max-width: 479.98px) {
    .hzpub-listing__thumb {
        width: 74px;
        height: 56px;
    }
}


/* ======================================================================
   Edit Listing — the header, and taking a listing down
   ======================================================================

   The same form as Add Listing, so almost nothing here is about fields. What
   edit mode adds is a way back out at the top and a way off the site at the
   bottom, plus the flash line My Listings shows afterwards.

   Structure taken from the car channel's own edit screen, read in a browser
   signed in as a seller who owns listings:

       heading      title left, "Back to My Listings" right, on one line
       back button  ghost treatment, same height as the form's own buttons
       actions      one primary ("Update Listing"), one ghost ("Cancel")

   Two things are deliberately different.

   The car screen puts its edit form inside the account shell, with the account
   navigation down the left. This page keeps the plain layout it already has,
   for two reasons: this form carries its own progress rail in the left column,
   so an account rail beside it would be two vertical rails and three columns
   at 1440; and the property my-account layout components belong to another
   session, so leaning on them here would be reaching into somebody else's work.

   The car screen has no way to take a listing down — Save and Cancel are all it
   offers. This one does, in its own card at the foot, because My Listings told
   sellers that withdrawing meant telephoning the team and that sentence was the
   last thing on that page which was not switched on.
   ==================================================================== */

.hzpub-head--edit {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 20px;
}

.hzpub-head__text {
    min-width: 0;
}

/* Nudged down so its cap-height sits on the title's baseline rather than on the
   title's box, which is 8px taller than the button. */
.hzpub-head__back {
    flex: 0 0 auto;
    margin-top: 4px;
    text-decoration: none;
}

.hzpub-head__back svg {
    /* The chevron points the way it goes. 2px stroke to match the tile
       controls in the gallery rather than the 1.6px body icons. */
    stroke-width: 2;
}

/* --------------------------------------------------------- withdrawing --- */

/*
    Its own card, below the form, rather than a third button in the row beside
    Save. The row is pressed every time an edit is saved; this cannot be undone
    from this page. Putting them side by side would make the irreversible action
    a neighbour of the routine one, at the same size, in the same row.

    Not red-bordered. The card is quiet and the button carries the warning,
    because a red-framed panel on a page whose purpose is editing reads as an
    error state on the form above it.
*/
.hzpub-danger {
    margin-top: 18px;
}

.hzpub-danger__title {
    margin: 0 0 6px;
}

.hzpub-danger__text {
    max-width: 62ch;
    margin: 0 0 14px;
    color: var(--hzpub-muted);
    font-size: 13px;
    line-height: 1.6;
}

.hzpub-danger__text a {
    color: var(--hzpub-accent);
    text-decoration: none;
}

.hzpub-danger__text a:hover {
    text-decoration: underline;
}

.hzpub-danger__form {
    margin: 0;
}

/*
    The destructive button. White with a red border and red ink, filling red
    only on hover — the same escalation the theme's own secondary buttons use,
    so it is legible as a button first and as a warning second. A permanently
    filled red button beside a form is a thing people avoid reading.
*/
.hzpub-btn--danger {
    border-color: #f0b4b4;
    background: #ffffff;
    color: #b42318;
}

.hzpub-btn--danger:hover {
    border-color: #b42318;
    background: #b42318;
    color: #ffffff;
}

.hzpub-btn--danger:focus-visible {
    outline: 2px solid #b42318;
    outline-offset: 2px;
}

/* ------------------------------------------------------------- the flash --- */

/*
    What happened, on the page it happened to. Shown once, after a withdrawal,
    above the listing table — where the row that changed is, so the sentence and
    the row it is about are read together.
*/
.hzpub-flash {
    margin: 0 0 14px;
    border: 1px solid #a7f3d0;
    border-radius: var(--hzpub-radius);
    background: #ecfdf5;
    padding: 11px 14px;
    color: #047857;
    font-size: 13px;
    line-height: 1.55;
}

.hzpub-flash--error {
    border-color: #f0b4b4;
    background: #fef3f2;
    color: #b42318;
}

/* ------------------------------------------------------------ narrow --- */

/*
    The heading stacks before the title has to wrap around the button. 640px
    rather than a breakpoint from the table above, because this is a different
    piece of geometry: it is the point at which "Back to My Listings" and the
    words "Edit listing" stop fitting on one line together.
*/
@media (max-width: 639.98px) {
    .hzpub-head--edit {
        flex-direction: column;
        gap: 12px;
    }

    .hzpub-head__back {
        margin-top: 0;
    }
}

/* ============================================================================
   DELETING A LISTING, AND THE TAB STRIP THAT HOLDS THE DELETED ONES
   ============================================================================

   Added for the seller's delete action. Plain CSS appended to this sheet and
   cache-busted by the filemtime the view already stamps on it — there is no
   build step in this project's stylesheet path and running one would replace
   the live sheet with something that cannot be reproduced.

   Written with logical properties (padding-inline, inset-inline-start) rather
   than left/right, so the Arabic rendering needs no [dir="rtl"] block and there
   is no second set of rules to keep in step with this one. Flex and grid follow
   the writing direction on their own.
   -------------------------------------------------------------------------- */

/* ------------------------------------------------------- the tab strip --- */

/*
    This screen had no tabs before. It has them now because a deleted listing is
    kept only so its seller can look at it, which is a different job from the
    rest of the list, and a state whose whole purpose is "somewhere to go and
    see" needs somewhere to be.

    Links, not buttons, and the state is in the query string: a tab is this same
    page with one filter, so it is bookmarkable, it survives a reload, and it
    works with scripting off. The strip is a <nav>, and the current tab carries
    aria-current="page", so it is announced as the current one rather than only
    looking like it.
*/
.hzpub-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin: 0 0 18px;
    border-bottom: 1px solid var(--hzpub-line);
}

.hzpub-tab {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    /* The 2px transparent bottom border is the same thickness as the current
       tab's coloured one, so selecting a tab does not move the row. */
    padding: 9px 12px;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    color: var(--hzpub-muted);
    font-size: 13px;
    font-weight: 500;
    white-space: nowrap;
    text-decoration: none;
}

.hzpub-tab:hover {
    color: var(--hzpub-ink);
}

.hzpub-tab:focus-visible {
    outline: 2px solid var(--hzpub-accent);
    outline-offset: -2px;
    border-radius: var(--hzpub-radius);
}

.hzpub-tab[aria-current="page"] {
    border-bottom-color: var(--hzpub-accent);
    color: var(--hzpub-accent);
}

/* The count beside the label. `tabular-nums` so a strip whose figures change
   between tabs does not shuffle the labels sideways. */
.hzpub-tab__count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    padding: 2px 6px;
    border-radius: 999px;
    background: #f1f2f5;
    color: var(--hzpub-muted);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
}

.hzpub-tab[aria-current="page"] .hzpub-tab__count {
    background: #EAF1FF;
    color: var(--hzpub-accent);
}

/* ---------------------------------------------------- the deleted state --- */

/*
    Deleted has to be distinguishable from Withdrawn at a glance, and
    .hzpub-badge--muted is already withdrawn's grey. So this is the only red on
    the screen: terminal rather than alarming, and dark enough on its own
    background to pass AA for small text.

    Green still means exactly one thing here — a member of the public can see
    this right now — and nothing below changes that.
*/
.hzpub-badge--deleted {
    border-color: #fecdd3;
    background: #fff1f2;
    color: #9f1239;
}

/*
    A deleted row is legible but plainly spent. The photograph loses its colour
    and the title stops looking like a link, because for a deleted listing it is
    not one — there is no page behind it. Text stays at --hzpub-muted, which is
    4.8:1 on white, rather than being faded until it cannot be read.
*/
.hzpub-listing--deleted .hzpub-listing__thumb img {
    opacity: 0.55;
    filter: grayscale(1);
}

.hzpub-listing--deleted .hzpub-listing__title,
.hzpub-listing--deleted .hzpub-listing__price {
    color: var(--hzpub-muted);
}

/* When did they delete it. Under the badge, beside the qualifier. */
.hzpub-listing__deleted-on {
    display: block;
    margin: 3px 0 0;
    color: var(--hzpub-muted);
    font-size: 11px;
    line-height: 1.4;
}

/* ------------------------------------------------- the delete control --- */

/*
    THE THIRD BUTTON IN THE ROW, AND WHY IT IS ALLOWED TO BE THERE

    The note in listings.blade.php says a row of three buttons, one of them
    irreversible, is a row where the wrong one gets pressed. That is still true,
    and it is the reason this control is shaped the way it is rather than the
    reason it is absent:

      - It is not the irreversible action. It is a LINK to a confirmation page.
        The worst a mis-press can do is show the seller a page asking a
        question, which costs them one click of Back.
      - It is quieter than its neighbours — no fill, no border until hovered —
        so View and Edit stay the two things the eye lands on.
      - It sits apart, below a gap, rather than being the third in an even
        stack.
*/
.hzpub-listing__actions .hzpub-del {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    margin-top: 3px;
    padding: 6px 10px;
    border: 1px solid transparent;
    border-radius: var(--hzpub-radius);
    background: none;
    color: #b91c1c;
    font-family: inherit;
    font-size: 12px;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
}

.hzpub-del:hover {
    border-color: #fecaca;
    background: #fef2f2;
}

.hzpub-del:focus-visible {
    outline: 2px solid #b91c1c;
    outline-offset: 2px;
}

.hzpub-del svg {
    width: 13px;
    height: 13px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* ------------------------------------------- a tab with nothing in it --- */

/*
    Not the same thing as an account with no listings at all, which has its own
    panel inviting the seller to add one. Here they have listings; this tab just
    is not where they are.
*/
.hzpub-none {
    margin: 0;
    padding: 34px 20px;
    border: 1px dashed var(--hzpub-line-strong);
    border-radius: var(--hzpub-radius);
    text-align: center;
}

.hzpub-none__title {
    margin: 0 0 6px;
    color: var(--hzpub-ink);
    font-size: 14px;
    font-weight: 600;
}

.hzpub-none__text {
    margin: 0;
    color: var(--hzpub-muted);
    font-size: 13px;
    line-height: 1.55;
}

/* ------------------------------------------- the confirmation page --- */

/*
    Deleting is confirmed on a page of its own rather than in a scripted
    dialogue. A dialogue is not there when scripting is off, and this is the one
    action a seller takes on this site that nobody can undo for them — not the
    Hagzi team, not an administrator, not the seller by listing the property
    again, because that produces a different listing with a different reference.

    So the consequences are set out in front of the button, and the button that
    keeps the listing is the one that looks like the default.
*/
.hzpub-del-subject {
    margin: 0 0 18px;
    padding: 14px 16px;
    border: 1px solid var(--hzpub-line);
    border-radius: var(--hzpub-radius);
    background: #fafbfc;
}

.hzpub-del-subject__title {
    margin: 0;
    color: var(--hzpub-ink);
    font-size: 15px;
    font-weight: 600;
    line-height: 1.4;
}

.hzpub-del-subject__ref {
    display: block;
    margin-top: 5px;
    color: var(--hzpub-muted);
    font-size: 12px;
    font-variant-numeric: tabular-nums;
}

.hzpub-del-points {
    display: grid;
    gap: 11px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.hzpub-del-points li {
    position: relative;
    /* Logical, so the marker sits on the starting edge in both directions. */
    padding-inline-start: 20px;
    color: var(--hzpub-ink);
    font-size: 13.5px;
    line-height: 1.6;
}

.hzpub-del-points li::before {
    position: absolute;
    inset-inline-start: 3px;
    top: 8px;
    width: 6px;
    height: 6px;
    border-radius: 999px;
    background: #b91c1c;
    content: "";
}

/* The alternative to deleting, for the seller who only wants the listing off
   the site. Set apart from the consequences above because it is a way out, not
   another thing that is about to happen. */
.hzpub-del-alt {
    margin: 18px 0 0;
    padding: 12px 14px;
    border: 1px solid var(--hzpub-line);
    border-radius: var(--hzpub-radius);
    background: #f6f7f9;
    color: var(--hzpub-muted);
    font-size: 12.5px;
    line-height: 1.6;
}

.hzpub-del-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-top: 22px;
}

/* ------------------------------------------------------------ narrow --- */

@media (max-width: 479.98px) {
    /*
        The strip wraps at this width rather than scrolling.

        It was written to scroll, on the reasoning that stacking would push the
        table off the first screen. Measured, that rule was wrong twice over.

        The `overflow-x` never took effect: `.hzac-card` is a grid item of
        `.hzac__main`, and a grid item's automatic minimum size is its
        min-content width, which the un-wrapped strip sets. So the card came out
        378px wide inside a 358px column and carried itself, the table and the
        note 4px past the left edge of a 390px viewport. Arabic showed it first,
        because the labels there are longest.

        Forcing the card to shrink does stop the overflow, but then the strip
        really does scroll, and the tab that falls off the end is `Deleted` --
        the newest tab, the one with no other route to it, and exactly the "last
        tab nobody finds" the original note was worried about.

        Wrapping costs one extra row here and keeps all four tabs visible and
        reachable without a gesture. The `min-width` below stays as a guard, so
        a longer label in some future locale cannot put the card back outside
        its column.
    */
    .hzpub-tabs {
        flex-wrap: wrap;
    }

    /*
        Scoped with `:has()` so this reaches only the one card that carries the
        tab strip; `.hzac-card` is shared with every other account screen and is
        not this feature's to change.
    */
    .hzac-card:has(.hzpub-tabs) {
        min-width: 0;
    }

    .hzpub-del-actions .hzpub-btn,
    .hzpub-del-actions .hzpub-del {
        width: 100%;
    }
}

/* The heading above the list of consequences on the delete confirmation page.
   Sized between the card title and the body text, so it reads as a warning
   rather than as a second page title. */
.hzpub-del-heading {
    margin: 0 0 12px;
    color: #9f1239;
    font-size: 13.5px;
    font-weight: 600;
    letter-spacing: 0.01em;
    text-transform: none;
}

/* ============================================================================
   My Listings — awaiting review
   ============================================================================

   The fourth badge tone. The other three are declared far above: green for
   live, grey for withdrawn, red for deleted.

   Amber rather than reusing the grey, and the reason is the same one the green
   comment gives about colour being part of the sentence. Withdrawn and awaiting
   review are both "not on the site", so a shared grey would be defensible — but
   one of them has finished and the other is going somewhere, and a seller
   checking on a submission should be able to see which without reading the
   qualifier underneath.

   These are the amber values the admin's own pending panel uses
   (resources/admin/property/approve-action.blade.php renders amber-300 on
   amber-50), so a listing awaiting review reads the same colour to the seller
   and to the reviewer.
   ========================================================================= */

.hzpub-badge--pending {
    border-color: #fcd34d;
    background: #fffbeb;
    color: #92400e;
}

/* ============================================================================
   My Listings — searching and sorting  (.hzpub-filters)
   ============================================================================

   A row between the tab strip and the table: a search field that grows, a sort
   select that does not, and an Apply button that is invisible until it is
   focused.

   WHY IT SITS INSIDE THE CARD AND UNDER THE TABS

   The order on screen is the order the filters compose: the tab is the coarsest
   cut, then the term, then the order within what is left. Putting the row above
   the tabs would read as though it filtered the tabs.

   WHY THE FIELD GROWS AND THE SELECT DOES NOT

   The select's width is its longest option and that is a fixed quantity; the
   field's useful width is however much is left. `min-width: 0` on the field is
   what lets it shrink below its content width instead of pushing the row wider
   than the card — the same trap the tab strip hit at 390px, recorded at the
   foot of this file.
   ========================================================================= */

.hzpub-filters {
    display: flex;
    align-items: center;
    /* Wraps rather than scrolls. Two rows of controls is a readable answer to a
       narrow screen; a horizontally scrolling toolbar is not. */
    flex-wrap: wrap;
    gap: 10px;
    min-width: 0;
    margin: 0 0 14px;
    padding: 0 18px;
}

/* ------------------------------------------------------------- the field --- */

.hzpub-search {
    position: relative;
    display: flex;
    min-width: 0;
    flex: 1 1 220px;
    align-items: center;
}

.hzpub-search svg {
    /*
        Logical, not `left`. In Arabic the field's text starts on the right and
        the magnifier has to start there with it; `left: 11px` would leave the
        icon sitting on top of the text's end.
    */
    position: absolute;
    inset-inline-start: 11px;
    width: 15px;
    height: 15px;
    fill: none;
    pointer-events: none;
    stroke: var(--hzpub-muted, #6b7280);
    stroke-linecap: round;
    stroke-width: 2;
}

.hzpub-search input {
    width: 100%;
    height: 38px;
    min-width: 0;
    box-sizing: border-box;
    /* Room for the magnifier at the start, wherever the start is. */
    padding-inline: 34px 12px;
    border: 1px solid var(--hzpub-line-strong, #d6dae1);
    border-radius: var(--hzpub-radius, 6px);
    background: #fff;
    color: var(--hzpub-ink, #12141a);
    font: inherit;
    font-size: 13.5px;
}

.hzpub-search input::placeholder {
    color: var(--hzpub-muted, #6b7280);
}

.hzpub-search input:focus-visible {
    border-color: var(--hzpub-accent, #0745D9);
    outline: 2px solid color-mix(in srgb, var(--hzpub-accent, #0745D9) 28%, transparent);
    outline-offset: 1px;
}

/* Safari and Chrome draw their own clear button inside type=search; it sits on
   the wrong side in Arabic and duplicates the Clear link. */
.hzpub-search input::-webkit-search-cancel-button {
    display: none;
}

/* -------------------------------------------------------------- the sort --- */

.hzpub-sort {
    display: flex;
    min-width: 0;
    align-items: center;
    gap: 8px;
}

.hzpub-sort label {
    color: var(--hzpub-muted, #6b7280);
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
}

.hzpub-sort select {
    max-width: 100%;
    height: 38px;
    box-sizing: border-box;
    padding-inline: 10px 26px;
    border: 1px solid var(--hzpub-line-strong, #d6dae1);
    border-radius: var(--hzpub-radius, 6px);
    background: #fff;
    color: var(--hzpub-ink, #12141a);
    font: inherit;
    font-size: 13.5px;
}

.hzpub-sort select:focus-visible {
    border-color: var(--hzpub-accent, #0745D9);
    outline: 2px solid color-mix(in srgb, var(--hzpub-accent, #0745D9) 28%, transparent);
    outline-offset: 1px;
}

/* ------------------------------------------------------------- the clear --- */

/* Quieter than either control it undoes. It is a way back, not a third filter. */
.hzpub-clear {
    padding: 0 2px;
    color: var(--hzpub-muted, #6b7280);
    font-size: 12.5px;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.hzpub-clear:hover {
    color: var(--hzpub-accent, #0745D9);
}

/* ---------------------------------------------------------- Apply, on focus --- */

/*
    Present, focusable, and invisible until it is focused.

    Not `display: none` and not `visibility: hidden`: both would take it out of
    the tab order, and with scripting off this is the only control that can
    apply a sort. The clip-rect idiom keeps it in the order and in the
    accessibility tree while taking it off the screen, and :focus-visible hands
    it back so a keyboard reader can see what they have landed on.
*/
.hzpub-onfocus:not(:focus-visible) {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    border: 0;
    margin: 0;
    clip-path: inset(50%);
    overflow: hidden;
    white-space: nowrap;
}

/* ============================================================================
   The delete dialogue  (.hzdel)
   ============================================================================

   Progressive enhancement over the confirmation page. The page is unchanged and
   still reachable; this is the same question without a round trip. See
   public/themes/property/property-delete-modal.js.

   WHY THE BACKDROP IS THE DIALOGUE ELEMENT

   One element, not two. #hzdel-dialog is the full-viewport sheet AND the thing
   with role="dialog", and the panel is its only child. That is what lets the
   script treat "the click landed on #hzdel-dialog itself" as a click on the
   backdrop without hit-testing coordinates, and it is one fewer node to keep in
   step.

   WHY IT IS NOT <dialog>

   showModal() would bring the backdrop, the top layer and the Escape handling
   for nothing. It would also bring its own focus rules and an inert page, which
   is harder to reason about next to a Vue application that remounts this markup
   — and `hidden` on a plain element is a state the no-script case gets right by
   default. The parts <dialog> would have supplied are eleven lines of script and
   they are written out where they can be read.
   ========================================================================= */

.hzdel {
    position: fixed;
    z-index: 60;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 18px;
    /* Logical shorthand: this covers the viewport whichever way the document
       runs. */
    inset: 0;
    background: rgba(17, 20, 26, .55);
}

/* `hidden` has to win against `display: flex`. Without this the attribute is
   ignored and the dialogue is drawn over the page from the moment it loads --
   including for readers with no script at all, who would then be looking at a
   dialogue with nothing filled in. */
.hzdel[hidden] {
    display: none;
}

/* The document does not scroll behind an open dialogue. Set on <html> by the
   script, and removed by it. */
.hzdel-locked {
    overflow: hidden;
}

.hzdel__panel {
    /* Tall content on a short viewport scrolls the panel, not the page behind
       it -- and 100dvh rather than vh so a mobile browser's collapsing toolbar
       does not cut the buttons off. */
    max-height: calc(100dvh - 36px);
    width: 100%;
    max-width: 460px;
    overflow-y: auto;
    padding: 22px;
    border-radius: 10px;
    background: #fff;
    box-shadow: 0 18px 48px rgba(17, 20, 26, .24);
}

.hzdel__title {
    /* Red, because the action is destructive. This is the palette's only other
       licensed use of red alongside the Delete control and the deleted badge --
       the primary #0745D9 is not a warning colour and must not be asked to
       carry one. */
    margin: 0 0 14px;
    color: #9f1239;
    font-size: 17px;
    font-weight: 600;
    line-height: 1.3;
}

/* Which listing. Boxed so it reads as the subject of the question rather than
   as another sentence of the warning. */
.hzdel__subject {
    padding: 11px 13px;
    border: 1px solid var(--hzpub-line, #e7e9ee);
    border-radius: var(--hzpub-radius, 6px);
    margin: 0 0 16px;
    background: #fcfcfd;
}

.hzdel__name {
    margin: 0;
    color: var(--hzpub-ink, #12141a);
    font-size: 14px;
    font-weight: 600;
    line-height: 1.4;
    /* A seller's own title, unbounded in length. Wraps rather than being
       clipped: this is the one place the full title has to be readable, because
       it is what distinguishes the row they meant from the row next to it. */
    overflow-wrap: anywhere;
}

.hzdel__ref {
    display: block;
    margin-top: 3px;
    color: var(--hzpub-muted, #6b7280);
    font-size: 11.5px;
}

.hzdel__heading {
    margin: 0 0 8px;
    color: #9f1239;
    font-size: 13px;
    font-weight: 600;
}

.hzdel__points {
    /* Logical padding, so the markers sit inside the text on both sides. */
    padding: 0;
    padding-inline-start: 18px;
    margin: 0 0 20px;
    color: #4b5563;
    font-size: 12.5px;
    line-height: 1.65;
}

.hzdel__points li + li {
    margin-top: 5px;
}

.hzdel__actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
}

/* The form is only a wrapper for the submit button, so it must not introduce a
   block that breaks the row. */
.hzdel__actions form {
    display: contents;
}

/* ------------------------------------------------------------------ narrow --- */

@media (max-width: 479.98px) {
    /*
        Full-width, stacked, and the destructive one last.

        Cancel is drawn first for the reason the markup gives -- it is the safe
        default and the first control reached -- and on a narrow screen "last"
        is also "furthest from the thumb resting at the bottom of the phone",
        which is the right place for the irreversible one.
    */
    .hzdel__actions {
        flex-direction: column;
        align-items: stretch;
    }

    .hzdel__actions .hzpub-btn {
        width: 100%;
        justify-content: center;
    }

    .hzdel__panel {
        padding: 18px;
    }

    /*
        The toolbar stacks. The sort keeps its label beside the select rather
        than above it -- two rows for one control on a 390px screen is a row
        spent on a word.
    */
    .hzpub-filters {
        align-items: stretch;
        flex-direction: column;
        padding-inline: 14px;
    }

    .hzpub-sort {
        justify-content: space-between;
    }

    .hzpub-sort select {
        flex: 1 1 auto;
        min-width: 0;
    }
}

/* Mobile My Listings: compact controls and actions without desktop flex sizing. */
@media (max-width: 767.98px) {
    .hzac-card:has(.hzpub-tabs) {
        min-width: 0;
    }

    .hzpub-tabs {
        --hzpub-accent: var(--hagzi-primary, #0745D9);
        flex-wrap: nowrap;
        overflow-x: auto;
        overscroll-behavior-x: contain;
        gap: 0;
        margin-bottom: 14px;
        scrollbar-width: thin;
    }

    .hzpub-tab {
        flex: 0 0 auto;
        min-height: 44px;
        padding-inline: 12px;
    }

    .hzpub-filters {
        flex-direction: column;
        flex-wrap: nowrap;
        align-items: stretch;
        gap: 10px;
        padding-inline: 14px;
    }

    .hzpub-search,
    .hzpub-sort {
        width: 100%;
        max-width: 100%;
    }

    .hzpub-search {
        /* The desktop 220px flex basis becomes vertical space in a column. */
        flex: 0 0 auto;
    }

    .hzpub-sort {
        justify-content: space-between;
    }

    .hzpub-sort select {
        flex: 1 1 auto;
        min-width: 0;
    }

    .hzpub-search input,
    .hzpub-sort select {
        height: 44px;
        font-size: 16px;
    }

    .hzpub-listing {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 12px;
    }

    .hzpub-listing__property {
        grid-column: 1 / -1;
    }

    .hzpub-listing__price,
    .hzpub-listing__status {
        min-width: 0;
    }

    .hzpub-listing__status {
        text-align: end;
    }

    .hzpub-listing__actions {
        grid-column: 1 / -1;
        grid-auto-flow: column;
        grid-auto-columns: minmax(0, 1fr);
        gap: 8px;
    }

    .hzpub-listing__actions .hzpub-btn,
    .hzpub-listing__actions .hzpub-del {
        min-width: 0;
        min-height: 44px;
        margin-top: 0;
        padding-inline: 6px;
    }
}
