Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions assets/css/builder.css
Original file line number Diff line number Diff line change
Expand Up @@ -2246,6 +2246,70 @@ os-checkbox-label.atfb-check {
background: var( --atfb-accent-soft );
}

/* A control and the chrome that belongs to it — a repeater and its add button,
a page break and its navigation — kept together as one block. */
.atfb-preview__stack {
display: flex;
flex-direction: column;
gap: 6px;
}

/* The hint keeps `.atf-hint` from the front end, so its size and colour are the
theme's. This only stops an empty one collapsing: an editable with nothing in
it still has to be a target you can click, and the placeholder inside it is
what invites the first hint anybody writes. */
.atfb-preview__hint {
margin: 4px 0 0;
}

.atfb-preview__hint .atfb-editable {
display: block;
min-block-size: 1lh;
}

/* A button whose words are the editable part. `.atf-button` gives it the
theme's real fill, radius and padding; it is a `<span>` rather than a
`<button>` because a button element cannot hold a caret. */
.atfb-preview__button {
display: inline-flex;
align-items: center;
/* The stack is a column flex container, so without this the button grows to
the full width of the card and stops reading as a button at all. */
align-self: flex-start;
cursor: text;
}

/* Inherited rather than themed: the text sits on the button's own colour, and
the editing outline has to be visible against a filled accent as well as
against a pale secondary. */
.atfb-preview__button-text {
color: inherit;
font: inherit;
}

.atfb-preview__button-text:focus {
background: none;
outline-color: currentcolor;
}

.atfb-preview__button-text:hover {
outline-color: currentcolor;
}

/* The page break's own navigation, drawn small: it is a preview of the buttons
that close the page, not a call to action on the canvas. */
.atfb-preview__nav {
display: flex;
gap: 8px;
margin: 0;
}

/* The step's name, which is what the progress indicator shows. */
.atfb-progress-name {
margin: 0;
font-weight: 600;
}

/* What an elaborate control says instead of pretending to be itself. */
.atfb-preview__summary {
margin: 0;
Expand Down
114 changes: 114 additions & 0 deletions assets/css/form.css
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,49 @@
justify-content: space-between;
}

/* Every button in a form, reset against the site's theme.
*
* A form is dropped into somebody else's theme, and themes style bare `button`
* elements — Astra's inline CSS sets `padding: 15px 30px`, a box-shadow and a
* background on `.menu-toggle, button, .ast-button, …`. Ours declared `border`
* and `background` and left everything else, so the repeater's 28px × turned
* into a 60×30 slab with a drop shadow hanging over the row's corner.
*
* Declaring only the properties we happen to care about is what loses these
* fights. A form has to look the same on any theme, so every button starts from
* the same place and the rules below paint from there. `.atf-form button` weighs
* (0,1,1), which beats the bare `button` in a theme's selector list.
*
* Wrapped in `:where()`, which contributes nothing to specificity — so this
* weighs (0,1,0): enough to beat a theme's bare `button`, and low enough that
* every `.atf-button` rule below still wins on source order. Written plainly as
* `.atf-form button` it weighed (0,1,1) and beat our own components instead,
* which stripped the submit button and the repeater's "Add another" back to
* bare text — a reset that resets the wrong side of the fight.
*
* Anything a theme commonly sets belongs in this list; if a control starts
* looking wrong on one theme and right on another, this is the first place to
* look. */
.atf-form :where( button ) {
margin: 0;
padding: 0;
border: 0;
border-radius: 0;
background: none;
box-shadow: none;
color: inherit;
font: inherit;
line-height: var( --atf-line-height );
letter-spacing: inherit;
text-transform: none;
text-decoration: none;
min-inline-size: 0;
block-size: auto;
inline-size: auto;
appearance: none;
}


.atf-button {
display: inline-flex;
align-items: center;
Expand Down Expand Up @@ -1254,3 +1297,74 @@
background-color: Highlight;
}
}

/* --- The Toggle, drawn as a switch -----------------------------------------
*
* `switch` and `consent` are the same control underneath — one checkbox — and
* they should not look the same. A switch says "this setting is on"; consent
* says "I have agreed", which is a statement a tick box makes and a switch does
* not. A field type called Toggle that rendered a checkbox was the name lying
* about the control.
*
* Sized in `em` from the field's own font, so it scales with a theme's type
* rather than needing tokens of its own — a theme that sets a bigger base size
* gets a bigger switch without touching anything. */
.atf-form .atf-toggle--switch .atf-toggle__input {
inline-size: 2.2em;
block-size: 1.25em;
border-radius: 1em;
/* The track, not a box: the switch's own shape overrides the tick box's
radius token, which is the one place a theme's `radius-check` must not
apply. */
padding: 0;
flex: 0 0 auto;
position: relative;
transition: background-color var( --atf-transition-duration ) var( --atf-transition-easing );
}

/* The knob. `::before` is the tick box's mark, reused — so the checked state
moves the knob rather than drawing a tick. */
.atf-form .atf-toggle--switch .atf-toggle__input::before {
content: "";
position: absolute;
inset-block-start: 50%;
inset-inline-start: 0.12em;
inline-size: 0.95em;
block-size: 0.95em;
border-radius: 50%;
background-color: var( --atf-border );
transform: translateY( -50% ) scale( 1 );
clip-path: none;
transition: inset-inline-start var( --atf-transition-duration ) var( --atf-transition-easing ),
background-color var( --atf-transition-duration ) var( --atf-transition-easing );
}

.atf-form .atf-toggle--switch .atf-toggle__input:checked::before {
inset-inline-start: calc( 100% - 1.07em );
background-color: var( --atf-accent-text );
transform: translateY( -50% ) scale( 1 );
}

/* The track fills with the accent when on, which is what the tick box does too
— the state reads the same across every control in the form. */
.atf-form .atf-toggle--switch .atf-toggle__input:checked {
background-color: var( --atf-accent );
border-color: var( --atf-accent );
}

/* A switch is a control, not a word: it sits on the line with its label rather
than being nudged onto the first line of a paragraph like a tick box. */
.atf-form .atf-toggle--switch {
align-items: center;
}

.atf-form .atf-toggle--switch .atf-toggle__label {
margin-block-start: 0;
}

@media ( prefers-reduced-motion: reduce ) {
.atf-form .atf-toggle--switch .atf-toggle__input,
.atf-form .atf-toggle--switch .atf-toggle__input::before {
transition: none;
}
}
Loading
Loading