@citolab/qti-components 8.0.2 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cdn/index.global.js +1 -1
- package/cdn/index.js +751 -813
- package/dist/base.d.ts +63 -6
- package/dist/base.js +7 -1
- package/dist/{chunk-CK7AV2UJ.js → chunk-43XBJ47H.js} +3 -3
- package/dist/{chunk-7V4HJFHW.js → chunk-6ITD55QE.js} +2 -2
- package/dist/{chunk-HQESINXH.js → chunk-7D3NKAGZ.js} +137 -3
- package/dist/chunk-7D3NKAGZ.js.map +1 -0
- package/dist/{chunk-HBSWJC3B.js → chunk-CRLXQZFA.js} +595 -260
- package/dist/chunk-CRLXQZFA.js.map +1 -0
- package/dist/{chunk-IJD53WY6.js → chunk-HDEG6BAZ.js} +15 -15
- package/dist/{chunk-IJD53WY6.js.map → chunk-HDEG6BAZ.js.map} +1 -1
- package/dist/{chunk-RSVRS5AK.js → chunk-LMGJOBJA.js} +4 -4
- package/dist/{chunk-ZII6M3SN.js → chunk-M7K5C522.js} +2 -2
- package/dist/{chunk-J5SQLKNP.js → chunk-OIUK5BFU.js} +22 -6
- package/dist/{chunk-J5SQLKNP.js.map → chunk-OIUK5BFU.js.map} +1 -1
- package/dist/{chunk-VAE6HBKR.js → chunk-OVBG223G.js} +88 -62
- package/dist/chunk-OVBG223G.js.map +1 -0
- package/dist/{chunk-TWPXES3S.js → chunk-Q6ZK4LRH.js} +30 -6
- package/dist/chunk-Q6ZK4LRH.js.map +1 -0
- package/dist/chunk-TLTYXWW7.js +7 -0
- package/dist/chunk-TLTYXWW7.js.map +1 -0
- package/dist/{chunk-NJQHUUTN.js → chunk-U7YCXDYC.js} +2 -2
- package/dist/{chunk-BQFWCZFH.js → chunk-UC3T3NI3.js} +2 -2
- package/dist/{chunk-7AVWRQIS.js → chunk-YLRMOX6C.js} +63 -77
- package/dist/chunk-YLRMOX6C.js.map +1 -0
- package/dist/{computed.types.d-DpKIYO6e.d.ts → computed.types.d-CJarqC6s.d.ts} +12 -0
- package/dist/corrections.d.ts +14 -4
- package/dist/corrections.js +8 -8
- package/dist/elements.d.ts +1 -2
- package/dist/elements.js +4 -4
- package/dist/index.d.ts +7 -7
- package/dist/index.js +30 -14
- package/dist/interactions.js +3 -3
- package/dist/item.css +451 -532
- package/dist/item.d.ts +1 -1
- package/dist/item.js +5 -5
- package/dist/loader.d.ts +1 -1
- package/dist/loader.js +2 -2
- package/dist/processing.d.ts +64 -14
- package/dist/processing.js +10 -2
- package/dist/qti-components-jsx.d.ts +8139 -7358
- package/dist/{qti-condition-expression.d-aMvBvpc6.d.ts → qti-condition-expression.d-CYwXOUb1.d.ts} +1 -1
- package/dist/{qti-expression.d-BietT_8b.d.ts → qti-expression.d-B_-m9emA.d.ts} +11 -1
- package/dist/{qti-feedback.d-DZbad0RN.d.ts → qti-feedback.d-B1EIF-fU.d.ts} +1 -0
- package/dist/{qti-test.d-_YAlhDbt.d.ts → qti-test.d-C6lCEMRB.d.ts} +38 -3
- package/dist/test.d.ts +5 -5
- package/dist/test.js +8 -6
- package/dist/transformers.d.ts +1 -1
- package/dist/transformers.js +1 -1
- package/package.json +9 -9
- package/dist/chunk-7AVWRQIS.js.map +0 -1
- package/dist/chunk-G6GFQDVN.js +0 -7
- package/dist/chunk-G6GFQDVN.js.map +0 -1
- package/dist/chunk-HBSWJC3B.js.map +0 -1
- package/dist/chunk-HQESINXH.js.map +0 -1
- package/dist/chunk-TWPXES3S.js.map +0 -1
- package/dist/chunk-VAE6HBKR.js.map +0 -1
- /package/dist/{chunk-CK7AV2UJ.js.map → chunk-43XBJ47H.js.map} +0 -0
- /package/dist/{chunk-7V4HJFHW.js.map → chunk-6ITD55QE.js.map} +0 -0
- /package/dist/{chunk-RSVRS5AK.js.map → chunk-LMGJOBJA.js.map} +0 -0
- /package/dist/{chunk-ZII6M3SN.js.map → chunk-M7K5C522.js.map} +0 -0
- /package/dist/{chunk-NJQHUUTN.js.map → chunk-U7YCXDYC.js.map} +0 -0
- /package/dist/{chunk-BQFWCZFH.js.map → chunk-UC3T3NI3.js.map} +0 -0
package/dist/item.css
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
@layer qti-base, qti-components, qti-extended;
|
|
3
|
+
|
|
3
4
|
@layer qti-components.reset, qti-components.global, qti-components.interactions.base,
|
|
4
5
|
qti-components.interactions.brand, qti-components.interactions.states,
|
|
5
6
|
qti-components.interactions.corrections, qti-components.elements, qti-components.overrides;
|
|
@@ -14,6 +15,7 @@
|
|
|
14
15
|
* Nothing is left unlayered: unlayered CSS outranks every layer, so a single stray rule here would
|
|
15
16
|
* sit above the whole theme AND above the `qti-extended` slot consumers are told to author in.
|
|
16
17
|
*/
|
|
18
|
+
|
|
17
19
|
@layer qti-base{
|
|
18
20
|
/* https://www.imsglobal.org/sites/default/files/spec/qti/v3/guide/img/qti3p0.css */
|
|
19
21
|
/* ============================
|
|
@@ -1446,6 +1448,7 @@
|
|
|
1446
1448
|
text-orientation: upright;
|
|
1447
1449
|
}
|
|
1448
1450
|
}
|
|
1451
|
+
|
|
1449
1452
|
@layer qti-base{
|
|
1450
1453
|
|
|
1451
1454
|
.qti-layout-row {
|
|
@@ -1577,6 +1580,7 @@
|
|
|
1577
1580
|
* block is appended after every declared layer, which would put brand paint above the state and
|
|
1578
1581
|
* correction paint it is meant to sit under. Deleting the two names moved 7 of the 17 VRT baselines.
|
|
1579
1582
|
*/
|
|
1583
|
+
|
|
1580
1584
|
@layer qti-components.reset{
|
|
1581
1585
|
@scope (qti-item-body, .ProseMirror) {
|
|
1582
1586
|
:scope,
|
|
@@ -1628,6 +1632,7 @@
|
|
|
1628
1632
|
}
|
|
1629
1633
|
}
|
|
1630
1634
|
}
|
|
1635
|
+
|
|
1631
1636
|
@layer qti-components.elements{
|
|
1632
1637
|
|
|
1633
1638
|
/**
|
|
@@ -1699,6 +1704,7 @@
|
|
|
1699
1704
|
* these blocks (--qti-correct reads --qti-success) is layer-independent. Nothing here renders
|
|
1700
1705
|
* differently for being grouped this way.
|
|
1701
1706
|
*/
|
|
1707
|
+
|
|
1702
1708
|
/* ============================================================================
|
|
1703
1709
|
* global — the foundation every layer reads.
|
|
1704
1710
|
* ========================================================================== */
|
|
@@ -1893,6 +1899,7 @@
|
|
|
1893
1899
|
}
|
|
1894
1900
|
}
|
|
1895
1901
|
}
|
|
1902
|
+
|
|
1896
1903
|
/* ============================================================================
|
|
1897
1904
|
* interactions.base — interaction-local geometry. Neutral, no judgement colour.
|
|
1898
1905
|
* ========================================================================== */
|
|
@@ -2064,6 +2071,7 @@
|
|
|
2064
2071
|
--qti-drag-padding: var(--qti-spacing) 0.8em;
|
|
2065
2072
|
}
|
|
2066
2073
|
}
|
|
2074
|
+
|
|
2067
2075
|
/* ============================================================================
|
|
2068
2076
|
* interactions.states — state paint. Selection, drag, and drop-target highlight.
|
|
2069
2077
|
* ========================================================================== */
|
|
@@ -2110,6 +2118,7 @@
|
|
|
2110
2118
|
--qti-drop-highlight-border-width: 2px;
|
|
2111
2119
|
}
|
|
2112
2120
|
}
|
|
2121
|
+
|
|
2113
2122
|
/* ============================================================================
|
|
2114
2123
|
* interactions.corrections — answer-key and judgement paint.
|
|
2115
2124
|
* ========================================================================== */
|
|
@@ -2134,15 +2143,18 @@
|
|
|
2134
2143
|
/* QTI base — shared theme utilities and semantic mixins. Only styles >=2 interactions share.
|
|
2135
2144
|
* They read the variables in qti-variables.css; a substrate re-colours by overriding those, not
|
|
2136
2145
|
* by editing these. Split from qti-base.css. */
|
|
2146
|
+
|
|
2137
2147
|
/* ============================================================================
|
|
2138
2148
|
* Shared semantic mixins. Only styles ≥2 interactions share belong here.
|
|
2139
2149
|
* A substrate expresses its look by overriding the --qti-* variables above
|
|
2140
2150
|
* (value first), not by editing these.
|
|
2141
2151
|
* ========================================================================== */
|
|
2152
|
+
|
|
2142
2153
|
/*
|
|
2143
2154
|
* Semantic PostCSS mixins. Interaction files wire these to their own parts and states; the mixins
|
|
2144
2155
|
* own the shared visual vocabulary.
|
|
2145
2156
|
*/
|
|
2157
|
+
|
|
2146
2158
|
/*
|
|
2147
2159
|
* A candidate correction, painted through the corrected element's own role.
|
|
2148
2160
|
*
|
|
@@ -2159,6 +2171,7 @@
|
|
|
2159
2171
|
*
|
|
2160
2172
|
* `candidate-tint` below survives for the one corrected element with no role: qti-hottext.
|
|
2161
2173
|
*/
|
|
2174
|
+
|
|
2162
2175
|
/*
|
|
2163
2176
|
* THE paint contract. Every visual component is, at rest, a bordered box on the theme's surface.
|
|
2164
2177
|
* This mixin binds each PAINT property to a variable exactly once, so a state — or a theme —
|
|
@@ -2189,6 +2202,7 @@
|
|
|
2189
2202
|
* rings) and a MULTI-SLOT box-shadow (so an element's resting lift, in-flight elevation and focus
|
|
2190
2203
|
* ring compose instead of the last one winning — the documented four-rule box-shadow contention).
|
|
2191
2204
|
*/
|
|
2205
|
+
|
|
2192
2206
|
/*
|
|
2193
2207
|
* A drag: the movable token a candidate drags into a gap, a drop target or an order slot.
|
|
2194
2208
|
*
|
|
@@ -2206,6 +2220,7 @@
|
|
|
2206
2220
|
* Under content-box the clone's padding would be added to the width the drag code measured off the
|
|
2207
2221
|
* bank drag, and it would jump the instant it was picked up.
|
|
2208
2222
|
*/
|
|
2223
|
+
|
|
2209
2224
|
/*
|
|
2210
2225
|
* The hole a drag leaves behind: lifted mid-drag, or spent because its copy is already placed.
|
|
2211
2226
|
*
|
|
@@ -2216,6 +2231,7 @@
|
|
|
2216
2231
|
* bank would reflow around a hole 20px narrower than the thing that left it. Measured in
|
|
2217
2232
|
* drag-drop.invariance.spec.ts, "a spent drag keeps its footprint".
|
|
2218
2233
|
*/
|
|
2234
|
+
|
|
2219
2235
|
/*
|
|
2220
2236
|
* The drag handle glyph.
|
|
2221
2237
|
*
|
|
@@ -2228,6 +2244,7 @@
|
|
|
2228
2244
|
* else. This one is in flow and takes real width, which is why it reserves an explicit width/height
|
|
2229
2245
|
* rather than leaning on the glyph's intrinsic size.
|
|
2230
2246
|
*/
|
|
2247
|
+
|
|
2231
2248
|
/*
|
|
2232
2249
|
* The radio and the checkbox: the other two things this theme draws as boxes, and so the other two
|
|
2233
2250
|
* paint roles. A control is a bordered box on the theme's surface exactly like a chip is, and now it
|
|
@@ -2248,6 +2265,7 @@
|
|
|
2248
2265
|
* not a paint slot. Centring the mark is the component's job — qti-simple-choice.styles.ts already
|
|
2249
2266
|
* flex-centres [part='control'].
|
|
2250
2267
|
*/
|
|
2268
|
+
|
|
2251
2269
|
/*
|
|
2252
2270
|
* The mark inside a control at rest — the box the tick or dot is drawn into. Structural.
|
|
2253
2271
|
*
|
|
@@ -2260,10 +2278,12 @@
|
|
|
2260
2278
|
* border — so it would silently shrink by the border width and change with it. Multiplying the token
|
|
2261
2279
|
* keeps the mark proportional to the control's outer size, which is the size anyone reasons about.
|
|
2262
2280
|
*/
|
|
2281
|
+
|
|
2263
2282
|
/* A choice with its native control shown (radio/checkbox visible) is the button component with its
|
|
2264
2283
|
border made TRANSPARENT — no visible box, but the 1px edge is still there, so it is the same box
|
|
2265
2284
|
as the `.qti-input-control-hidden` choice (which keeps the border visible because the whole choice
|
|
2266
2285
|
is the control). Only the border COLOUR differs between the two, never the geometry. */
|
|
2286
|
+
|
|
2267
2287
|
/*
|
|
2268
2288
|
* The mark a checked control shows: a dot for a radio, a tick for a checkbox.
|
|
2269
2289
|
*
|
|
@@ -2272,6 +2292,7 @@
|
|
|
2272
2292
|
* `control-selected`), so the two belong together: override --checkbox-background-color and you will
|
|
2273
2293
|
* usually want --checkbox-mark-color with it. `white` is the resting value, not a fixed one.
|
|
2274
2294
|
*/
|
|
2295
|
+
|
|
2275
2296
|
/*
|
|
2276
2297
|
* `act`, `readonly` and `dis` used to live here. They are written out at their call sites now, for
|
|
2277
2298
|
* two different reasons.
|
|
@@ -2293,16 +2314,20 @@
|
|
|
2293
2314
|
*
|
|
2294
2315
|
* `act-bor` was deleted outright: zero call sites anywhere in the repo.
|
|
2295
2316
|
*/
|
|
2317
|
+
|
|
2296
2318
|
/* `foc` stays a mixin, deliberately, and is the one state still painting a property directly.
|
|
2297
2319
|
* Twenty call sites read it, and it draws a `box-shadow` — the property the contract has NOT bound
|
|
2298
2320
|
* (see `paint` above). Routing it through --<role>-box-shadow would not fix anything: focus would
|
|
2299
2321
|
* then fight the resting lift and the in-flight elevation over one slot, last-declared winning,
|
|
2300
2322
|
* which is the four-rule contention already documented in qti-variables.css. The intended fix
|
|
2301
2323
|
* recorded there is a single `outline` on `:focus-visible`, and that is its own VRT-checked step. */
|
|
2324
|
+
|
|
2302
2325
|
/* A choice — the clickable box a candidate picks. Nothing but the resting paint box; its padding is
|
|
2303
2326
|
the interaction's (qti-choice-interaction.css), because a choice's box differs per interaction and
|
|
2304
2327
|
a chip's does not. */
|
|
2328
|
+
|
|
2305
2329
|
/* A text field: the paint box, plus the cursor that says you can type in it. */
|
|
2330
|
+
|
|
2306
2331
|
/*
|
|
2307
2332
|
* A drop target: the paint box with a DASHED edge, the one thing that distinguishes it from every
|
|
2308
2333
|
* other role.
|
|
@@ -2317,9 +2342,11 @@
|
|
|
2317
2342
|
* dashed edge onto any chip standing in the drop (it did — a chip in a drop went dashed). Now that
|
|
2318
2343
|
* the chip reads --drag-border-style, the drop's value inherits past it harmlessly.
|
|
2319
2344
|
*/
|
|
2345
|
+
|
|
2320
2346
|
/* The initial `display: none` moved to `validationMessage` in qti-base — the message is a shadow
|
|
2321
2347
|
node, and `Interaction.reportValidity` already owns showing and hiding it with an inline style.
|
|
2322
2348
|
What is left here is paint. */
|
|
2349
|
+
|
|
2323
2350
|
/*
|
|
2324
2351
|
* The three roles qti-inline-choice-interaction is built from. They are separate roles rather than
|
|
2325
2352
|
* one, because they nest: the menu and the message live in the field's shadow root, so under a
|
|
@@ -2330,12 +2357,14 @@
|
|
|
2330
2357
|
* `menu` the popover the options are listed in.
|
|
2331
2358
|
* `message` the validation box. Its warning colouring is the interaction's, not the role's.
|
|
2332
2359
|
*/
|
|
2360
|
+
|
|
2333
2361
|
/*
|
|
2334
2362
|
* A drag in flight. The other `drag` modifier — applied with `drag`, never instead of it.
|
|
2335
2363
|
*
|
|
2336
2364
|
* `rotate` is paint: a transform never reflows, which is what lets a drag tilt under the cursor
|
|
2337
2365
|
* without the bank shifting behind it.
|
|
2338
2366
|
*/
|
|
2367
|
+
|
|
2339
2368
|
/*
|
|
2340
2369
|
* A drag darkens a little under the pointer. The one hover affordance in the theme.
|
|
2341
2370
|
*
|
|
@@ -2363,16 +2392,15 @@
|
|
|
2363
2392
|
Handed to qti-simple-choice.styles.ts, which owns the label's box; this was an
|
|
2364
2393
|
`::part(label) { display: inline !important }`. */
|
|
2365
2394
|
--qti-choice-label-display: inline;
|
|
2395
|
+
}
|
|
2366
2396
|
|
|
2367
|
-
|
|
2397
|
+
qti-choice-interaction qti-simple-choice {
|
|
2368
2398
|
padding: var(--qti-padding-box);
|
|
2369
2399
|
width: -moz-fit-content;
|
|
2370
2400
|
width: fit-content;
|
|
2371
2401
|
cursor: pointer;
|
|
2372
2402
|
}
|
|
2373
|
-
|
|
2374
|
-
&.qti-input-control-hidden {
|
|
2375
|
-
& qti-simple-choice {
|
|
2403
|
+
qti-choice-interaction.qti-input-control-hidden qti-simple-choice {
|
|
2376
2404
|
background-color: var(--button-background-color, var(--qti-component-background-color));
|
|
2377
2405
|
background-image: var(--button-background-image, var(--qti-component-background-image));
|
|
2378
2406
|
border-width: var(--button-border-width, var(--qti-component-border-width));
|
|
@@ -2384,14 +2412,11 @@
|
|
|
2384
2412
|
opacity: var(--button-opacity, var(--qti-component-opacity));
|
|
2385
2413
|
filter: var(--button-filter, var(--qti-component-filter));
|
|
2386
2414
|
--qti-control-display: none;
|
|
2387
|
-
|
|
2415
|
+
}
|
|
2416
|
+
:is(qti-choice-interaction.qti-input-control-hidden qti-simple-choice):focus {
|
|
2388
2417
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
2389
2418
|
}
|
|
2390
|
-
|
|
2391
|
-
}
|
|
2392
|
-
|
|
2393
|
-
&:not(.qti-input-control-hidden) {
|
|
2394
|
-
& qti-simple-choice {
|
|
2419
|
+
qti-choice-interaction:not(.qti-input-control-hidden) qti-simple-choice {
|
|
2395
2420
|
background-color: var(--button-background-color, var(--qti-component-background-color));
|
|
2396
2421
|
background-image: var(--button-background-image, var(--qti-component-background-image));
|
|
2397
2422
|
border-width: var(--button-border-width, var(--qti-component-border-width));
|
|
@@ -2406,52 +2431,46 @@
|
|
|
2406
2431
|
gap: 0.5rem;
|
|
2407
2432
|
outline: none;
|
|
2408
2433
|
cursor: pointer;
|
|
2434
|
+
}
|
|
2409
2435
|
|
|
2410
|
-
|
|
2436
|
+
:is(qti-choice-interaction:not(.qti-input-control-hidden) qti-simple-choice):focus {
|
|
2411
2437
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
2412
2438
|
}
|
|
2413
2439
|
|
|
2414
|
-
|
|
2440
|
+
:is(qti-choice-interaction:not(.qti-input-control-hidden) qti-simple-choice)::part(control-mark) {
|
|
2415
2441
|
width: calc(var(--qti-control-size) * 0.625);
|
|
2416
2442
|
height: calc(var(--qti-control-size) * 0.625);
|
|
2417
2443
|
}
|
|
2418
|
-
}
|
|
2419
|
-
}
|
|
2420
|
-
}
|
|
2421
2444
|
}
|
|
2445
|
+
|
|
2422
2446
|
@layer qti-components.interactions.states {
|
|
2423
|
-
qti-choice-interaction {
|
|
2424
|
-
&.qti-input-control-hidden qti-simple-choice {
|
|
2425
2447
|
/* A selected choice, repainted through the button role's slots rather than by re-declaring the
|
|
2426
2448
|
properties — the choice is `@mixin button`, so switching a variable is all a state has to do.
|
|
2427
2449
|
This used to be `@mixin act` followed by two direct declarations, and half of `act` was dead
|
|
2428
2450
|
on arrival: it set `background-color: var(--qti-bg-active)` and the very next line overwrote
|
|
2429
2451
|
it with the selected fill. Only its border-colour ever survived, which is written out here. */
|
|
2430
|
-
|
|
2452
|
+
:is(qti-choice-interaction.qti-input-control-hidden qti-simple-choice):is(:state(checked), [data-state~='checked']) {
|
|
2431
2453
|
--button-border-color: var(--qti-border-active);
|
|
2432
2454
|
--button-background-color: var(--qti-selected-bg);
|
|
2433
2455
|
--button-color: var(--qti-selected-color);
|
|
2434
2456
|
}
|
|
2435
2457
|
|
|
2436
|
-
|
|
2458
|
+
:is(qti-choice-interaction.qti-input-control-hidden qti-simple-choice):is(:state(readonly), [data-state~='readonly']) {
|
|
2437
2459
|
cursor: pointer;
|
|
2438
2460
|
}
|
|
2439
2461
|
|
|
2440
|
-
|
|
2462
|
+
:is(qti-choice-interaction.qti-input-control-hidden qti-simple-choice):is(:state(disabled), [data-state~='disabled']) {
|
|
2441
2463
|
cursor: not-allowed;
|
|
2442
2464
|
}
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
&:not(.qti-input-control-hidden) qti-simple-choice {
|
|
2446
|
-
&:state(readonly) {
|
|
2465
|
+
:is(qti-choice-interaction:not(.qti-input-control-hidden) qti-simple-choice):is(:state(readonly), [data-state~='readonly']) {
|
|
2447
2466
|
cursor: pointer;
|
|
2448
2467
|
}
|
|
2449
2468
|
|
|
2450
|
-
|
|
2469
|
+
:is(qti-choice-interaction:not(.qti-input-control-hidden) qti-simple-choice):is(:state(disabled), [data-state~='disabled']) {
|
|
2451
2470
|
cursor: not-allowed;
|
|
2452
2471
|
}
|
|
2453
2472
|
|
|
2454
|
-
|
|
2473
|
+
:is(qti-choice-interaction:not(.qti-input-control-hidden) qti-simple-choice):is(:state(radio), [data-state~='radio'])::part(control) {
|
|
2455
2474
|
background-color: var(--radio-background-color, var(--qti-component-background-color));
|
|
2456
2475
|
background-image: var(--radio-background-image, var(--qti-component-background-image));
|
|
2457
2476
|
border-width: var(--radio-border-width, var(--qti-component-border-width));
|
|
@@ -2469,13 +2488,12 @@
|
|
|
2469
2488
|
border-radius: var(--radio-border-radius, 100%);
|
|
2470
2489
|
}
|
|
2471
2490
|
|
|
2472
|
-
|
|
2473
|
-
&:state(checkbox):state(checked)::part(control) {
|
|
2491
|
+
:is(qti-choice-interaction:not(.qti-input-control-hidden) qti-simple-choice):is(:state(radio), [data-state~='radio']):is(:state(checked), [data-state~='checked'])::part(control),:is(qti-choice-interaction:not(.qti-input-control-hidden) qti-simple-choice):is(:state(checkbox), [data-state~='checkbox']):is(:state(checked), [data-state~='checked'])::part(control) {
|
|
2474
2492
|
border-color: var(--qti-primary);
|
|
2475
2493
|
background-color: var(--qti-primary);
|
|
2476
2494
|
}
|
|
2477
2495
|
|
|
2478
|
-
|
|
2496
|
+
:is(qti-choice-interaction:not(.qti-input-control-hidden) qti-simple-choice):is(:state(radio), [data-state~='radio']):is(:state(checked), [data-state~='checked'])::part(control-mark) {
|
|
2479
2497
|
/* 0.5 reproduces today's 8px at the default 1rem — see mark-size for why this is a fraction. */
|
|
2480
2498
|
width: calc(var(--qti-control-size) * 0.5);
|
|
2481
2499
|
height: calc(var(--qti-control-size) * 0.5);
|
|
@@ -2483,7 +2501,7 @@
|
|
|
2483
2501
|
border-radius: 100%;
|
|
2484
2502
|
}
|
|
2485
2503
|
|
|
2486
|
-
|
|
2504
|
+
:is(qti-choice-interaction:not(.qti-input-control-hidden) qti-simple-choice):is(:state(checkbox), [data-state~='checkbox'])::part(control) {
|
|
2487
2505
|
background-color: var(--checkbox-background-color, var(--qti-component-background-color));
|
|
2488
2506
|
background-image: var(--checkbox-background-image, var(--qti-component-background-image));
|
|
2489
2507
|
border-width: var(--checkbox-border-width, var(--qti-component-border-width));
|
|
@@ -2498,27 +2516,18 @@
|
|
|
2498
2516
|
height: var(--qti-control-size);
|
|
2499
2517
|
}
|
|
2500
2518
|
|
|
2501
|
-
|
|
2519
|
+
:is(qti-choice-interaction:not(.qti-input-control-hidden) qti-simple-choice):is(:state(checkbox), [data-state~='checkbox']):is(:state(checked), [data-state~='checked'])::part(control-mark) {
|
|
2502
2520
|
background-color: var(--checkbox-mark-color, white);
|
|
2503
2521
|
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='currentColor' width='100%' height='100%' viewBox='0 0 24 24'%3E%3Cpath d='M20.285 2l-11.285 11.567-5.286-5.011-3.714 3.716 9 8.728 15-15.285z'/%3E%3C/svg%3E");
|
|
2504
2522
|
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='currentColor' width='100%' height='100%' viewBox='0 0 24 24'%3E%3Cpath d='M20.285 2l-11.285 11.567-5.286-5.011-3.714 3.716 9 8.728 15-15.285z'/%3E%3C/svg%3E");
|
|
2505
2523
|
}
|
|
2506
|
-
}
|
|
2507
|
-
}
|
|
2508
2524
|
}
|
|
2525
|
+
|
|
2509
2526
|
@layer qti-components.interactions.corrections {
|
|
2510
|
-
|
|
2511
|
-
& qti-simple-choice {
|
|
2512
|
-
&:state(correct-response),
|
|
2513
|
-
&[data-correct-response='true'] {
|
|
2514
|
-
&::after {
|
|
2527
|
+
:is(:is(qti-choice-interaction qti-simple-choice):is(:state(correct-response), [data-state~='correct-response']),[data-correct-response='true']:is(qti-choice-interaction qti-simple-choice))::after {
|
|
2515
2528
|
content: '\02714';
|
|
2516
2529
|
color: var(--qti-correct);
|
|
2517
2530
|
}
|
|
2518
|
-
}
|
|
2519
|
-
}
|
|
2520
|
-
|
|
2521
|
-
&.qti-input-control-hidden qti-simple-choice {
|
|
2522
2531
|
/*
|
|
2523
2532
|
* Paint only. This used to set `border: 3px` over a 1px base and add `padding-right: 30px`,
|
|
2524
2533
|
* so revealing the answer key grew every correct choice and reflowed the list around it.
|
|
@@ -2527,12 +2536,12 @@
|
|
|
2527
2536
|
* costs no layout. The 30px that kept the label clear of the tick is reserved in the base
|
|
2528
2537
|
* rule for this variant, whether or not a tick ever appears.
|
|
2529
2538
|
*/
|
|
2530
|
-
|
|
2531
|
-
&[data-correct-response='true'] {
|
|
2539
|
+
:is(qti-choice-interaction.qti-input-control-hidden qti-simple-choice):is(:state(correct-response), [data-state~='correct-response']),[data-correct-response='true']:is(qti-choice-interaction.qti-input-control-hidden qti-simple-choice) {
|
|
2532
2540
|
border-color: var(--qti-correct) !important;
|
|
2533
2541
|
box-shadow: inset 0 0 0 2px var(--qti-correct);
|
|
2542
|
+
}
|
|
2534
2543
|
|
|
2535
|
-
|
|
2544
|
+
:is(:is(qti-choice-interaction.qti-input-control-hidden qti-simple-choice):is(:state(correct-response), [data-state~='correct-response']),[data-correct-response='true']:is(qti-choice-interaction.qti-input-control-hidden qti-simple-choice))::after {
|
|
2536
2545
|
content: '\02714';
|
|
2537
2546
|
color: var(--qti-correct);
|
|
2538
2547
|
position: absolute;
|
|
@@ -2541,94 +2550,75 @@
|
|
|
2541
2550
|
font-size: 1.2em;
|
|
2542
2551
|
font-weight: bold;
|
|
2543
2552
|
}
|
|
2544
|
-
}
|
|
2545
2553
|
|
|
2546
2554
|
/* Candidate judgement follows checked/correct-response paint so it can
|
|
2547
2555
|
recolour the same stable box without changing its geometry. */
|
|
2548
|
-
|
|
2556
|
+
:is(qti-choice-interaction.qti-input-control-hidden qti-simple-choice):is(:state(candidate-correct), [data-state~='candidate-correct']) {
|
|
2549
2557
|
--button-background-color: var(--qti-correct-light);
|
|
2550
2558
|
--button-color: var(--qti-correct);
|
|
2551
2559
|
--button-border-color: var(--qti-correct);
|
|
2552
2560
|
--button-box-shadow: none;
|
|
2553
2561
|
}
|
|
2554
2562
|
|
|
2555
|
-
|
|
2563
|
+
:is(qti-choice-interaction.qti-input-control-hidden qti-simple-choice):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']) {
|
|
2556
2564
|
--button-background-color: var(--qti-incorrect-light);
|
|
2557
2565
|
--button-color: var(--qti-incorrect);
|
|
2558
2566
|
--button-border-color: var(--qti-incorrect);
|
|
2559
2567
|
--button-box-shadow: none;
|
|
2560
2568
|
}
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
&:not(.qti-input-control-hidden) qti-simple-choice {
|
|
2564
|
-
&:state(candidate-correct) {
|
|
2569
|
+
:is(qti-choice-interaction:not(.qti-input-control-hidden) qti-simple-choice):is(:state(candidate-correct), [data-state~='candidate-correct']) {
|
|
2565
2570
|
background-color: transparent;
|
|
2571
|
+
}
|
|
2566
2572
|
|
|
2567
|
-
|
|
2568
|
-
&:state(checkbox):state(checked)::part(control) {
|
|
2573
|
+
:is(qti-choice-interaction:not(.qti-input-control-hidden) qti-simple-choice):is(:state(candidate-correct), [data-state~='candidate-correct']):is(:state(radio), [data-state~='radio']):is(:state(checked), [data-state~='checked'])::part(control),:is(qti-choice-interaction:not(.qti-input-control-hidden) qti-simple-choice):is(:state(candidate-correct), [data-state~='candidate-correct']):is(:state(checkbox), [data-state~='checkbox']):is(:state(checked), [data-state~='checked'])::part(control) {
|
|
2569
2574
|
border-color: var(--qti-correct);
|
|
2570
2575
|
background-color: var(--qti-correct);
|
|
2571
2576
|
}
|
|
2572
|
-
}
|
|
2573
2577
|
|
|
2574
|
-
|
|
2578
|
+
:is(qti-choice-interaction:not(.qti-input-control-hidden) qti-simple-choice):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']) {
|
|
2575
2579
|
background-color: transparent;
|
|
2580
|
+
}
|
|
2576
2581
|
|
|
2577
|
-
|
|
2578
|
-
&:state(checkbox):state(checked)::part(control) {
|
|
2582
|
+
:is(qti-choice-interaction:not(.qti-input-control-hidden) qti-simple-choice):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']):is(:state(radio), [data-state~='radio']):is(:state(checked), [data-state~='checked'])::part(control),:is(qti-choice-interaction:not(.qti-input-control-hidden) qti-simple-choice):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']):is(:state(checkbox), [data-state~='checkbox']):is(:state(checked), [data-state~='checked'])::part(control) {
|
|
2579
2583
|
border-color: var(--qti-incorrect);
|
|
2580
2584
|
background-color: var(--qti-incorrect);
|
|
2581
2585
|
}
|
|
2582
|
-
|
|
2583
|
-
}
|
|
2584
|
-
}
|
|
2585
|
-
|
|
2586
|
-
.full-correct-response qti-choice-interaction {
|
|
2587
|
-
qti-simple-choice {
|
|
2588
|
-
&:state(radio):state(checked)::part(control),
|
|
2589
|
-
&:state(checkbox):state(checked)::part(control) {
|
|
2586
|
+
:is(:is(.full-correct-response qti-choice-interaction) qti-simple-choice):is(:state(radio), [data-state~='radio']):is(:state(checked), [data-state~='checked'])::part(control),:is(:is(.full-correct-response qti-choice-interaction) qti-simple-choice):is(:state(checkbox), [data-state~='checkbox']):is(:state(checked), [data-state~='checked'])::part(control) {
|
|
2590
2587
|
background-color: var(--qti-answer-bg);
|
|
2591
2588
|
color: var(--qti-answer-fg);
|
|
2592
2589
|
border-color: var(--qti-answer-border);
|
|
2593
2590
|
}
|
|
2594
2591
|
|
|
2595
|
-
|
|
2596
|
-
&:state(checkbox):state(checked)::part(control-mark) {
|
|
2592
|
+
:is(:is(.full-correct-response qti-choice-interaction) qti-simple-choice):is(:state(radio), [data-state~='radio']):is(:state(checked), [data-state~='checked'])::part(control-mark),:is(:is(.full-correct-response qti-choice-interaction) qti-simple-choice):is(:state(checkbox), [data-state~='checkbox']):is(:state(checked), [data-state~='checked'])::part(control-mark) {
|
|
2597
2593
|
background-color: var(--qti-answer-fg);
|
|
2598
2594
|
}
|
|
2599
|
-
}
|
|
2600
2595
|
|
|
2601
|
-
|
|
2596
|
+
.qti-input-control-hidden:is(.full-correct-response qti-choice-interaction) qti-simple-choice:is(:state(checked), [data-state~='checked']) {
|
|
2602
2597
|
background-color: var(--qti-answer-bg);
|
|
2603
2598
|
color: var(--qti-answer-fg);
|
|
2604
2599
|
border-color: var(--qti-answer-border);
|
|
2605
2600
|
}
|
|
2606
|
-
}
|
|
2607
2601
|
}
|
|
2602
|
+
|
|
2608
2603
|
@layer qti-components.interactions.base {
|
|
2609
|
-
|
|
2610
|
-
&.qti-selections-light {
|
|
2611
|
-
&:state(dragzone-active)::part(drags) {
|
|
2604
|
+
qti-graphic-gap-match-interaction.qti-selections-light:is(:state(dragzone-active), [data-state~='dragzone-active'])::part(drags) {
|
|
2612
2605
|
background-color: var(--qti-selections-light-bg);
|
|
2613
2606
|
border-color: var(--qti-selections-light-border);
|
|
2614
2607
|
}
|
|
2615
|
-
|
|
2608
|
+
qti-graphic-gap-match-interaction.qti-selections-light:is(:state(dragzone-enabled), [data-state~='dragzone-enabled'])::part(drags) {
|
|
2616
2609
|
background-color: var(--qti-selections-light-bg);
|
|
2617
2610
|
}
|
|
2618
|
-
|
|
2619
|
-
&.qti-selections-dark {
|
|
2620
|
-
&:state(dragzone-active)::part(drags) {
|
|
2611
|
+
qti-graphic-gap-match-interaction.qti-selections-dark:is(:state(dragzone-active), [data-state~='dragzone-active'])::part(drags) {
|
|
2621
2612
|
background-color: var(--qti-selections-dark-bg);
|
|
2622
2613
|
border-color: var(--qti-selections-dark-border);
|
|
2623
2614
|
}
|
|
2624
|
-
|
|
2615
|
+
qti-graphic-gap-match-interaction.qti-selections-dark:is(:state(dragzone-enabled), [data-state~='dragzone-enabled'])::part(drags) {
|
|
2625
2616
|
background-color: var(--qti-selections-dark-bg);
|
|
2626
2617
|
}
|
|
2627
|
-
|
|
2628
|
-
&:state(dragzone-active)::part(drags) {
|
|
2618
|
+
qti-graphic-gap-match-interaction:is(:state(dragzone-active), [data-state~='dragzone-active'])::part(drags) {
|
|
2629
2619
|
background-color: var(--qti-bg-active);
|
|
2630
2620
|
}
|
|
2631
|
-
|
|
2621
|
+
qti-graphic-gap-match-interaction:is(:state(dragzone-enabled), [data-state~='dragzone-enabled'])::part(drags) {
|
|
2632
2622
|
background-color: var(--qti-bg-active);
|
|
2633
2623
|
}
|
|
2634
2624
|
/*
|
|
@@ -2643,17 +2633,14 @@
|
|
|
2643
2633
|
/* A chip here is a tile filling its hotspot, so it centres its content — see
|
|
2644
2634
|
qti-gap-img.styles.ts and qti-gap-text.styles.ts. gap-match's chips hug their text instead,
|
|
2645
2635
|
which is why the justification is a variable rather than the element's default. */
|
|
2646
|
-
|
|
2647
|
-
& qti-gap-text {
|
|
2636
|
+
qti-graphic-gap-match-interaction qti-gap-img,qti-graphic-gap-match-interaction qti-gap-text {
|
|
2648
2637
|
--qti-drag-justify-content: center;
|
|
2649
2638
|
cursor: grab;
|
|
2650
2639
|
}
|
|
2651
2640
|
/* The placed chip, in the hotspot's shadow. Plain too, to match the bank. Focus ring only. */
|
|
2652
|
-
|
|
2653
|
-
&:focus {
|
|
2641
|
+
:is(qti-graphic-gap-match-interaction qti-associable-hotspot::part(drag)):focus {
|
|
2654
2642
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
2655
2643
|
}
|
|
2656
|
-
}
|
|
2657
2644
|
/*
|
|
2658
2645
|
* The hotspot centres its chip in qti-associable-hotspot.styles.ts.
|
|
2659
2646
|
*
|
|
@@ -2667,7 +2654,7 @@
|
|
|
2667
2654
|
* Adding a rule would be a redundant restatement of this line. Left as a note rather than code
|
|
2668
2655
|
* because the absence is the kind of thing that reads as an oversight.
|
|
2669
2656
|
*/
|
|
2670
|
-
|
|
2657
|
+
qti-graphic-gap-match-interaction qti-associable-hotspot {
|
|
2671
2658
|
border: 2px solid transparent;
|
|
2672
2659
|
/* No .qti-selections-* branches in here. They used to sit inside both of these blocks as
|
|
2673
2660
|
*descendant* selectors — and the class is on the interaction, an ancestor of this hotspot,
|
|
@@ -2675,19 +2662,20 @@
|
|
|
2675
2662
|
see the :state(filled) rules below.
|
|
2676
2663
|
A drop target lighting up mid-drag is not a "selection" anyway — Appendix B calls this
|
|
2677
2664
|
Selections theming, and the selection is the chip once it has landed. */
|
|
2678
|
-
|
|
2665
|
+
}
|
|
2666
|
+
[enabled]:is(qti-graphic-gap-match-interaction qti-associable-hotspot) {
|
|
2679
2667
|
background-color: var(--qti-bg-active);
|
|
2680
2668
|
}
|
|
2681
|
-
|
|
2669
|
+
[active]:is(qti-graphic-gap-match-interaction qti-associable-hotspot) {
|
|
2682
2670
|
background-color: var(--qti-bg-active);
|
|
2683
2671
|
}
|
|
2684
|
-
|
|
2672
|
+
[disabled]:is(qti-graphic-gap-match-interaction qti-associable-hotspot) {
|
|
2685
2673
|
cursor: not-allowed;
|
|
2686
|
-
|
|
2674
|
+
}
|
|
2675
|
+
[disabled]:is(qti-graphic-gap-match-interaction qti-associable-hotspot):not(:empty) {
|
|
2687
2676
|
cursor: default !important;
|
|
2688
2677
|
}
|
|
2689
|
-
|
|
2690
|
-
&:not(:empty) {
|
|
2678
|
+
:is(qti-graphic-gap-match-interaction qti-associable-hotspot):not(:empty) {
|
|
2691
2679
|
border-color: var(--qti-border) !important;
|
|
2692
2680
|
}
|
|
2693
2681
|
/*
|
|
@@ -2709,30 +2697,29 @@
|
|
|
2709
2697
|
|
|
2710
2698
|
/* `flex: 1` left with the rest of the drop's layout; dropRegion in qti-base gives a hosted
|
|
2711
2699
|
chip `flex: 0 0 auto`, which is the invariance rule this was quietly fighting. */
|
|
2712
|
-
|
|
2700
|
+
:is(qti-graphic-gap-match-interaction qti-associable-hotspot):not(:empty) > * {
|
|
2713
2701
|
transform: rotate(0);
|
|
2714
2702
|
box-shadow: 0 0 0 1px #e5e7eb;
|
|
2715
2703
|
}
|
|
2716
|
-
}
|
|
2717
2704
|
/* `:not(:empty)` tested light-DOM children. The hotspot renders its chips into its own shadow
|
|
2718
2705
|
root now, so it is always "empty" to a selector — `:state(filled)` is the occupancy hook. */
|
|
2719
|
-
|
|
2706
|
+
qti-graphic-gap-match-interaction.qti-selections-light qti-associable-hotspot:is(:state(filled), [data-state~='filled']) {
|
|
2720
2707
|
background-color: var(--qti-selections-light-bg) !important;
|
|
2721
2708
|
border-color: var(--qti-selections-light-border) !important;
|
|
2722
2709
|
}
|
|
2723
|
-
|
|
2710
|
+
qti-graphic-gap-match-interaction.qti-selections-dark qti-associable-hotspot:is(:state(filled), [data-state~='filled']) {
|
|
2724
2711
|
background-color: var(--qti-selections-dark-bg) !important;
|
|
2725
2712
|
border-color: var(--qti-selections-dark-border) !important;
|
|
2726
2713
|
}
|
|
2727
|
-
|
|
2714
|
+
qti-graphic-gap-match-interaction img {
|
|
2728
2715
|
margin: 0;
|
|
2729
2716
|
padding: 0;
|
|
2730
2717
|
}
|
|
2731
|
-
}
|
|
2732
2718
|
}
|
|
2719
|
+
|
|
2733
2720
|
@layer qti-components.interactions.states {
|
|
2734
|
-
qti-graphic-gap-match-interaction qti-gap-img:state(placeholder),
|
|
2735
|
-
qti-graphic-gap-match-interaction qti-gap-text:state(placeholder) {
|
|
2721
|
+
qti-graphic-gap-match-interaction qti-gap-img:is(:state(placeholder), [data-state~='placeholder']),
|
|
2722
|
+
qti-graphic-gap-match-interaction qti-gap-text:is(:state(placeholder), [data-state~='placeholder']) {
|
|
2736
2723
|
/* The hole a spent/lifted chip leaves. Like the chip (see `drag`), it sets NO fill / border /
|
|
2737
2724
|
shadow of its own — those inherit from the resting chip (neutral by default, the brand's fill
|
|
2738
2725
|
when an overlay is on), so a brand can restyle the hole via a `:state(placeholder)` overlay
|
|
@@ -2743,8 +2730,8 @@
|
|
|
2743
2730
|
pointer-events: none;
|
|
2744
2731
|
}
|
|
2745
2732
|
|
|
2746
|
-
qti-graphic-gap-match-interaction qti-gap-img:state(dragging),
|
|
2747
|
-
qti-graphic-gap-match-interaction qti-gap-text:state(dragging) {
|
|
2733
|
+
qti-graphic-gap-match-interaction qti-gap-img:is(:state(dragging), [data-state~='dragging']),
|
|
2734
|
+
qti-graphic-gap-match-interaction qti-gap-text:is(:state(dragging), [data-state~='dragging']) {
|
|
2748
2735
|
/* The hole a spent/lifted chip leaves. Like the chip (see `drag`), it sets NO fill / border /
|
|
2749
2736
|
shadow of its own — those inherit from the resting chip (neutral by default, the brand's fill
|
|
2750
2737
|
when an overlay is on), so a brand can restyle the hole via a `:state(placeholder)` overlay
|
|
@@ -2758,29 +2745,30 @@
|
|
|
2758
2745
|
pointer-events: none;
|
|
2759
2746
|
}
|
|
2760
2747
|
|
|
2761
|
-
qti-graphic-gap-match-interaction qti-gap-img:state(return-anchor),
|
|
2762
|
-
qti-graphic-gap-match-interaction qti-gap-text:state(return-anchor) {
|
|
2748
|
+
qti-graphic-gap-match-interaction qti-gap-img:is(:state(return-anchor), [data-state~='return-anchor']),
|
|
2749
|
+
qti-graphic-gap-match-interaction qti-gap-text:is(:state(return-anchor), [data-state~='return-anchor']) {
|
|
2763
2750
|
border-color: var(--qti-drop-highlight-border-color);
|
|
2764
2751
|
box-shadow: inset 0 0 0 var(--qti-drop-highlight-border-width, 2px)
|
|
2765
2752
|
color-mix(in srgb, var(--qti-drop-highlight-border-color) 55%, transparent);
|
|
2766
2753
|
}
|
|
2767
2754
|
|
|
2768
|
-
qti-graphic-gap-match-interaction qti-gap-img:state(placeholder) > *,
|
|
2769
|
-
qti-graphic-gap-match-interaction qti-gap-text:state(placeholder) > *,
|
|
2770
|
-
qti-graphic-gap-match-interaction qti-gap-img:state(dragging) > *,
|
|
2771
|
-
qti-graphic-gap-match-interaction qti-gap-text:state(dragging) > * {
|
|
2755
|
+
qti-graphic-gap-match-interaction qti-gap-img:is(:state(placeholder), [data-state~='placeholder']) > *,
|
|
2756
|
+
qti-graphic-gap-match-interaction qti-gap-text:is(:state(placeholder), [data-state~='placeholder']) > *,
|
|
2757
|
+
qti-graphic-gap-match-interaction qti-gap-img:is(:state(dragging), [data-state~='dragging']) > *,
|
|
2758
|
+
qti-graphic-gap-match-interaction qti-gap-text:is(:state(dragging), [data-state~='dragging']) > * {
|
|
2772
2759
|
visibility: hidden;
|
|
2773
2760
|
}
|
|
2774
2761
|
|
|
2775
|
-
qti-graphic-gap-match-interaction qti-associable-hotspot:state(hover),
|
|
2776
|
-
qti-graphic-gap-match-interaction qti-associable-hotspot:state(active) {
|
|
2762
|
+
qti-graphic-gap-match-interaction qti-associable-hotspot:is(:state(hover), [data-state~='hover']),
|
|
2763
|
+
qti-graphic-gap-match-interaction qti-associable-hotspot:is(:state(active), [data-state~='active']) {
|
|
2777
2764
|
background-color: var(--qti-drop-highlight-bg);
|
|
2778
2765
|
}
|
|
2779
2766
|
|
|
2780
|
-
qti-graphic-gap-match-interaction qti-associable-hotspot:state(enabled) {
|
|
2767
|
+
qti-graphic-gap-match-interaction qti-associable-hotspot:is(:state(enabled), [data-state~='enabled']) {
|
|
2781
2768
|
background-color: var(--qti-drop-highlight-enabled-bg);
|
|
2782
2769
|
}
|
|
2783
2770
|
}
|
|
2771
|
+
|
|
2784
2772
|
@layer qti-components.interactions.corrections {
|
|
2785
2773
|
/*
|
|
2786
2774
|
* The one place this interaction joins the shared chip vocabulary: its chips take no card, but they
|
|
@@ -2795,22 +2783,23 @@
|
|
|
2795
2783
|
* Moved here from qti-corrections.css, whose unscoped `:state(drag)` rule covered these chips
|
|
2796
2784
|
* along with everyone else's.
|
|
2797
2785
|
*/
|
|
2798
|
-
qti-graphic-gap-match-interaction :state(drag):state(candidate-correct),
|
|
2799
|
-
qti-graphic-gap-match-interaction qti-associable-hotspot::part(drag):state(candidate-correct) {
|
|
2786
|
+
qti-graphic-gap-match-interaction :is(:state(drag), [data-state~='drag']):is(:state(candidate-correct), [data-state~='candidate-correct']),
|
|
2787
|
+
qti-graphic-gap-match-interaction qti-associable-hotspot::part(drag):is(:state(candidate-correct), [data-state~='candidate-correct']) {
|
|
2800
2788
|
background-color: var(--qti-correct-light);
|
|
2801
2789
|
color: var(--qti-correct);
|
|
2802
2790
|
border-color: var(--qti-correct);
|
|
2803
2791
|
box-shadow: none;
|
|
2804
2792
|
}
|
|
2805
2793
|
|
|
2806
|
-
qti-graphic-gap-match-interaction :state(drag):state(candidate-incorrect),
|
|
2807
|
-
qti-graphic-gap-match-interaction qti-associable-hotspot::part(drag):state(candidate-incorrect) {
|
|
2794
|
+
qti-graphic-gap-match-interaction :is(:state(drag), [data-state~='drag']):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']),
|
|
2795
|
+
qti-graphic-gap-match-interaction qti-associable-hotspot::part(drag):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']) {
|
|
2808
2796
|
background-color: var(--qti-incorrect-light);
|
|
2809
2797
|
color: var(--qti-incorrect);
|
|
2810
2798
|
border-color: var(--qti-incorrect);
|
|
2811
2799
|
box-shadow: none;
|
|
2812
2800
|
}
|
|
2813
2801
|
}
|
|
2802
|
+
|
|
2814
2803
|
@layer qti-components.interactions.base {
|
|
2815
2804
|
qti-text-entry-interaction {
|
|
2816
2805
|
background-color: var(--text-background-color, var(--qti-component-background-color));
|
|
@@ -2824,8 +2813,9 @@
|
|
|
2824
2813
|
opacity: var(--text-opacity, var(--qti-component-opacity));
|
|
2825
2814
|
filter: var(--text-filter, var(--qti-component-filter));
|
|
2826
2815
|
cursor: text;
|
|
2816
|
+
}
|
|
2827
2817
|
|
|
2828
|
-
|
|
2818
|
+
qti-text-entry-interaction::part(input) {
|
|
2829
2819
|
color: var(--qti-fg);
|
|
2830
2820
|
font-family: inherit;
|
|
2831
2821
|
font-size: 1rem;
|
|
@@ -2836,31 +2826,29 @@
|
|
|
2836
2826
|
border: none;
|
|
2837
2827
|
background-color: transparent;
|
|
2838
2828
|
}
|
|
2839
|
-
}
|
|
2840
2829
|
}
|
|
2830
|
+
|
|
2841
2831
|
@layer qti-components.interactions.corrections {
|
|
2842
|
-
|
|
2843
|
-
&:state(candidate-partially-correct) {
|
|
2832
|
+
qti-text-entry-interaction:is(:state(candidate-partially-correct), [data-state~='candidate-partially-correct']) {
|
|
2844
2833
|
--text-background-color: var(--qti-partially-correct-light);
|
|
2845
2834
|
--text-color: var(--qti-partially-correct);
|
|
2846
2835
|
--text-border-color: var(--qti-partially-correct);
|
|
2847
2836
|
--text-box-shadow: none;
|
|
2848
2837
|
}
|
|
2849
2838
|
|
|
2850
|
-
|
|
2839
|
+
qti-text-entry-interaction:is(:state(candidate-correct), [data-state~='candidate-correct']) {
|
|
2851
2840
|
--text-background-color: var(--qti-correct-light);
|
|
2852
2841
|
--text-color: var(--qti-correct);
|
|
2853
2842
|
--text-border-color: var(--qti-correct);
|
|
2854
2843
|
--text-box-shadow: none;
|
|
2855
2844
|
}
|
|
2856
2845
|
|
|
2857
|
-
|
|
2846
|
+
qti-text-entry-interaction:is(:state(candidate-incorrect), [data-state~='candidate-incorrect']) {
|
|
2858
2847
|
--text-background-color: var(--qti-incorrect-light);
|
|
2859
2848
|
--text-color: var(--qti-incorrect);
|
|
2860
2849
|
--text-border-color: var(--qti-incorrect);
|
|
2861
2850
|
--text-box-shadow: none;
|
|
2862
2851
|
}
|
|
2863
|
-
}
|
|
2864
2852
|
|
|
2865
2853
|
/* The answer key, moved here from the shared qti-corrections.css: it names this interaction, so
|
|
2866
2854
|
this file owns it. */
|
|
@@ -2868,21 +2856,21 @@
|
|
|
2868
2856
|
background-color: var(--qti-answer-bg);
|
|
2869
2857
|
color: var(--qti-answer-fg);
|
|
2870
2858
|
border-color: var(--qti-answer-border);
|
|
2859
|
+
}
|
|
2871
2860
|
|
|
2872
|
-
|
|
2861
|
+
:is(.full-correct-response qti-text-entry-interaction)::part(input) {
|
|
2873
2862
|
color: var(--qti-answer-fg);
|
|
2874
2863
|
}
|
|
2875
2864
|
|
|
2876
|
-
|
|
2865
|
+
:is(.full-correct-response qti-text-entry-interaction)::part(answer) {
|
|
2877
2866
|
content: '';
|
|
2878
2867
|
background-color: var(--qti-answer-fg);
|
|
2879
2868
|
mask: var(--qti-check-mask) no-repeat center / contain;
|
|
2880
2869
|
-webkit-mask: var(--qti-check-mask) no-repeat center / contain;
|
|
2881
2870
|
}
|
|
2882
|
-
}
|
|
2883
2871
|
}
|
|
2872
|
+
|
|
2884
2873
|
@layer qti-components.interactions.base {
|
|
2885
|
-
qti-extended-text-interaction {
|
|
2886
2874
|
/*
|
|
2887
2875
|
* One block, and the ORDER inside it matters.
|
|
2888
2876
|
*
|
|
@@ -2896,7 +2884,7 @@
|
|
|
2896
2884
|
* slot is unset, so it falls through to --qti-component-color, which is `inherit` — the same
|
|
2897
2885
|
* colour the textarea already had.
|
|
2898
2886
|
*/
|
|
2899
|
-
|
|
2887
|
+
qti-extended-text-interaction::part(textarea) {
|
|
2900
2888
|
color: var(--qti-fg);
|
|
2901
2889
|
font-family: inherit;
|
|
2902
2890
|
font-size: 1rem;
|
|
@@ -2954,14 +2942,14 @@
|
|
|
2954
2942
|
* that makes the preserved indentation legible. Typography only — the box does not move, so
|
|
2955
2943
|
* the layout-invariance contract holds.
|
|
2956
2944
|
*/
|
|
2957
|
-
|
|
2945
|
+
qti-extended-text-interaction[format='preformatted']::part(textarea) {
|
|
2958
2946
|
font-family: monospace;
|
|
2959
2947
|
-moz-tab-size: 2;
|
|
2960
2948
|
-o-tab-size: 2;
|
|
2961
2949
|
tab-size: 2;
|
|
2962
2950
|
}
|
|
2963
|
-
}
|
|
2964
2951
|
}
|
|
2952
|
+
|
|
2965
2953
|
/*
|
|
2966
2954
|
* Corrections for the one interaction that cannot judge itself.
|
|
2967
2955
|
*
|
|
@@ -2981,8 +2969,7 @@
|
|
|
2981
2969
|
* positioned by the component and painted by ::part(correction-*) in qti-corrections.css.
|
|
2982
2970
|
*/
|
|
2983
2971
|
@layer qti-components.interactions.corrections {
|
|
2984
|
-
|
|
2985
|
-
&:state(candidate-correct)::part(textarea) {
|
|
2972
|
+
qti-extended-text-interaction:is(:state(candidate-correct), [data-state~='candidate-correct'])::part(textarea) {
|
|
2986
2973
|
--text-background-color: var(--qti-correct-light);
|
|
2987
2974
|
--text-color: var(--qti-correct);
|
|
2988
2975
|
--text-border-color: var(--qti-correct);
|
|
@@ -2995,20 +2982,19 @@
|
|
|
2995
2982
|
verbatim from the dead class-based rules, where it had never rendered and so was never seen to
|
|
2996
2983
|
be wrong. With --qti-fg now correctly resolving to `inherit`, it would have been more visibly
|
|
2997
2984
|
wrong still. */
|
|
2998
|
-
|
|
2985
|
+
qti-extended-text-interaction:is(:state(candidate-partially-correct), [data-state~='candidate-partially-correct'])::part(textarea) {
|
|
2999
2986
|
--text-background-color: var(--qti-partially-correct-light);
|
|
3000
2987
|
--text-color: var(--qti-partially-correct);
|
|
3001
2988
|
--text-border-color: var(--qti-partially-correct);
|
|
3002
2989
|
--text-box-shadow: none;
|
|
3003
2990
|
}
|
|
3004
2991
|
|
|
3005
|
-
|
|
2992
|
+
qti-extended-text-interaction:is(:state(candidate-incorrect), [data-state~='candidate-incorrect'])::part(textarea) {
|
|
3006
2993
|
--text-background-color: var(--qti-incorrect-light);
|
|
3007
2994
|
--text-color: var(--qti-incorrect);
|
|
3008
2995
|
--text-border-color: var(--qti-incorrect);
|
|
3009
2996
|
--text-box-shadow: none;
|
|
3010
2997
|
}
|
|
3011
|
-
}
|
|
3012
2998
|
}
|
|
3013
2999
|
/* This interaction's chip vocabulary — the bank chip, the placed chip, and the floating clone. One
|
|
3014
3000
|
such block per drag-drop interaction, opt-in; graphic-gap-match deliberately declares none. See
|
|
@@ -3026,7 +3012,7 @@
|
|
|
3026
3012
|
sat on document.body it was in a different tree from the adopted stylesheet, and nothing — no
|
|
3027
3013
|
part, no attribute — could style it. */
|
|
3028
3014
|
@layer qti-components.global {
|
|
3029
|
-
qti-gap-match-interaction :state(drag),
|
|
3015
|
+
qti-gap-match-interaction :is(:state(drag), [data-state~='drag']),
|
|
3030
3016
|
[data-drag-clone][data-drag-interaction='qti-gap-match-interaction'] {
|
|
3031
3017
|
/* Structural — the load-bearing box, never state-switched (layout-invariance contract).
|
|
3032
3018
|
box-sizing is deliberate: the clone is appended to document.body outside reset.css's
|
|
@@ -3077,7 +3063,7 @@
|
|
|
3077
3063
|
filter: var(--drag-filter, var(--qti-component-filter));
|
|
3078
3064
|
}
|
|
3079
3065
|
|
|
3080
|
-
qti-gap-match-interaction :state(drag)::part(control)::before,
|
|
3066
|
+
qti-gap-match-interaction :is(:state(drag), [data-state~='drag'])::part(control)::before,
|
|
3081
3067
|
qti-gap-match-interaction::part(drag-control)::before,
|
|
3082
3068
|
qti-gap-match-interaction ::part(drag-control)::before,
|
|
3083
3069
|
[data-drag-clone][data-drag-interaction='qti-gap-match-interaction']::part(control)::before {
|
|
@@ -3092,21 +3078,21 @@
|
|
|
3092
3078
|
-webkit-mask: var(--qti-grip-mask) no-repeat center / contain;
|
|
3093
3079
|
}
|
|
3094
3080
|
}
|
|
3081
|
+
|
|
3095
3082
|
@layer qti-components.interactions.base {
|
|
3096
|
-
qti-gap-match-interaction {
|
|
3097
3083
|
/* No qti-selections-light / -dark here. Appendix B.1 of the QTI 3 implementation guide defines
|
|
3098
3084
|
that class pair for qti-hotspot-interaction and qti-graphic-gap-match-interaction only, and no
|
|
3099
3085
|
item in this repo ever set it on a gap-match interaction. What was here overrode the neutral
|
|
3100
3086
|
drag-bank highlight below with --qti-light-* and --qti-dark-* colours that nothing could reach. */
|
|
3101
|
-
|
|
3087
|
+
qti-gap-match-interaction:is(:state(dragzone-active), [data-state~='dragzone-active'])::part(drags) {
|
|
3102
3088
|
background-color: var(--qti-bg-active);
|
|
3103
3089
|
}
|
|
3104
|
-
|
|
3090
|
+
qti-gap-match-interaction:is(:state(dragzone-enabled), [data-state~='dragzone-enabled'])::part(drags) {
|
|
3105
3091
|
background-color: var(--qti-bg-active);
|
|
3106
3092
|
}
|
|
3107
3093
|
/* Editor fake-drag projected into a filled <qti-gap>'s shadow. Same `drag`
|
|
3108
3094
|
styling so the editor preview matches runtime when a gap is filled. */
|
|
3109
|
-
|
|
3095
|
+
qti-gap-match-interaction qti-gap::part(drag) {
|
|
3110
3096
|
/* Structural — the load-bearing box, never state-switched (layout-invariance contract).
|
|
3111
3097
|
box-sizing is deliberate: the clone is appended to document.body outside reset.css's
|
|
3112
3098
|
@scope, so it inherits no border-box from anywhere else and this sets it. */
|
|
@@ -3154,20 +3140,20 @@
|
|
|
3154
3140
|
color: var(--drag-color, var(--qti-component-color));
|
|
3155
3141
|
opacity: var(--drag-opacity, var(--qti-component-opacity));
|
|
3156
3142
|
filter: var(--drag-filter, var(--qti-component-filter));
|
|
3157
|
-
|
|
3143
|
+
}
|
|
3158
3144
|
@media (hover: hover) {
|
|
3145
|
+
:is(qti-gap-match-interaction qti-gap::part(drag)):hover {
|
|
3159
3146
|
background-color: color-mix(
|
|
3160
3147
|
in srgb,
|
|
3161
3148
|
var(--drag-background-color, var(--qti-component-background-color)) 92%,
|
|
3162
3149
|
black
|
|
3163
3150
|
);
|
|
3164
|
-
}
|
|
3165
3151
|
}
|
|
3166
|
-
|
|
3152
|
+
}
|
|
3153
|
+
:is(qti-gap-match-interaction qti-gap::part(drag)):focus {
|
|
3167
3154
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
3168
3155
|
}
|
|
3169
|
-
|
|
3170
|
-
& qti-gap-text {
|
|
3156
|
+
qti-gap-match-interaction qti-gap-text {
|
|
3171
3157
|
/* Structural — the load-bearing box, never state-switched (layout-invariance contract).
|
|
3172
3158
|
box-sizing is deliberate: the clone is appended to document.body outside reset.css's
|
|
3173
3159
|
@scope, so it inherits no border-box from anywhere else and this sets it. */
|
|
@@ -3215,25 +3201,25 @@
|
|
|
3215
3201
|
color: var(--drag-color, var(--qti-component-color));
|
|
3216
3202
|
opacity: var(--drag-opacity, var(--qti-component-opacity));
|
|
3217
3203
|
filter: var(--drag-filter, var(--qti-component-filter));
|
|
3218
|
-
|
|
3204
|
+
}
|
|
3205
|
+
[dragging]:is(qti-gap-match-interaction qti-gap-text) {
|
|
3219
3206
|
pointer-events: none;
|
|
3220
3207
|
rotate: -2deg;
|
|
3221
3208
|
--drag-box-shadow: 0 8px 12px rgb(0 0 0 / 20%), 0 4px 8px rgb(0 0 0 / 10%);
|
|
3222
3209
|
}
|
|
3223
|
-
&:hover {
|
|
3224
3210
|
@media (hover: hover) {
|
|
3211
|
+
:is(qti-gap-match-interaction qti-gap-text):hover {
|
|
3225
3212
|
background-color: color-mix(
|
|
3226
3213
|
in srgb,
|
|
3227
3214
|
var(--drag-background-color, var(--qti-component-background-color)) 92%,
|
|
3228
3215
|
black
|
|
3229
3216
|
);
|
|
3230
|
-
}
|
|
3231
3217
|
}
|
|
3232
|
-
|
|
3218
|
+
}
|
|
3219
|
+
:is(qti-gap-match-interaction qti-gap-text):focus {
|
|
3233
3220
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
3234
3221
|
}
|
|
3235
|
-
|
|
3236
|
-
& qti-gap {
|
|
3222
|
+
qti-gap-match-interaction qti-gap {
|
|
3237
3223
|
background-color: var(--drop-background-color, var(--qti-component-background-color));
|
|
3238
3224
|
background-image: var(--drop-background-image, var(--qti-component-background-image));
|
|
3239
3225
|
border-width: var(--drop-border-width, var(--qti-component-border-width));
|
|
@@ -3261,22 +3247,23 @@
|
|
|
3261
3247
|
* every word on the line the instant a chip landed — the exact reflow qti-gap.styles.ts and
|
|
3262
3248
|
* drag-drop.invariance.spec.ts exist to prevent.
|
|
3263
3249
|
*/
|
|
3264
|
-
|
|
3250
|
+
}
|
|
3251
|
+
:is(qti-gap-match-interaction qti-gap):is(:state(filled), [data-state~='filled']):is(:not([match-max]),[match-max='1']) {
|
|
3265
3252
|
--drop-border-color: transparent;
|
|
3266
3253
|
}
|
|
3267
3254
|
|
|
3268
|
-
|
|
3255
|
+
[disabled]:is(qti-gap-match-interaction qti-gap) {
|
|
3269
3256
|
cursor: not-allowed;
|
|
3270
3257
|
/* `:not(:empty)` tested light-DOM children; the gap renders its chips into its own shadow
|
|
3271
3258
|
root now, so it is always "empty" to a selector. `:state(filled)` is the occupancy hook. */
|
|
3272
|
-
|
|
3259
|
+
}
|
|
3260
|
+
[disabled]:is(qti-gap-match-interaction qti-gap):is(:state(filled), [data-state~='filled']) {
|
|
3273
3261
|
cursor: default !important;
|
|
3274
3262
|
}
|
|
3275
|
-
|
|
3276
|
-
&[enabled] {
|
|
3263
|
+
[enabled]:is(qti-gap-match-interaction qti-gap) {
|
|
3277
3264
|
background-color: var(--qti-bg-active);
|
|
3278
3265
|
}
|
|
3279
|
-
|
|
3266
|
+
[active]:is(qti-gap-match-interaction qti-gap) {
|
|
3280
3267
|
background-color: var(--qti-bg-active);
|
|
3281
3268
|
}
|
|
3282
3269
|
/* The gap's own box — inline-flex, centred, baseline-aligned — is in qti-gap.styles.ts. */
|
|
@@ -3305,17 +3292,15 @@
|
|
|
3305
3292
|
*/
|
|
3306
3293
|
/* `flex: 0 0 auto` is dropRegion's, in qti-base — a drop hosts a chip, it never sizes one.
|
|
3307
3294
|
The rotate reset and the outline are paint. */
|
|
3308
|
-
|
|
3295
|
+
:is(qti-gap-match-interaction qti-gap)::part(drag) {
|
|
3309
3296
|
transform: rotate(0);
|
|
3310
3297
|
/* Through the drag slot so a correction (which sets --drag-box-shadow) composes over it
|
|
3311
3298
|
instead of this leaking onto a corrected chip. */
|
|
3312
3299
|
--drag-box-shadow: 0 0 0 1px #e5e7eb;
|
|
3313
3300
|
}
|
|
3314
|
-
}
|
|
3315
|
-
}
|
|
3316
3301
|
|
|
3317
3302
|
/* The source and placed chip share one visual component. */
|
|
3318
|
-
qti-gap-match-interaction qti-gap-text:state(drag),
|
|
3303
|
+
qti-gap-match-interaction qti-gap-text:is(:state(drag), [data-state~='drag']),
|
|
3319
3304
|
qti-gap-match-interaction qti-gap::part(drag) {
|
|
3320
3305
|
/* Structural — the load-bearing box, never state-switched (layout-invariance contract).
|
|
3321
3306
|
box-sizing is deliberate: the clone is appended to document.body outside reset.css's
|
|
@@ -3366,6 +3351,7 @@
|
|
|
3366
3351
|
filter: var(--drag-filter, var(--qti-component-filter));
|
|
3367
3352
|
}
|
|
3368
3353
|
}
|
|
3354
|
+
|
|
3369
3355
|
@layer qti-components.interactions.states {
|
|
3370
3356
|
/* One chip vocabulary across the bank and placed drags for gap-match only. */
|
|
3371
3357
|
qti-gap::part(drag) {
|
|
@@ -3418,7 +3404,7 @@
|
|
|
3418
3404
|
filter: var(--drag-filter, var(--qti-component-filter));
|
|
3419
3405
|
}
|
|
3420
3406
|
|
|
3421
|
-
qti-gap-match-interaction qti-gap-text:state(placeholder) {
|
|
3407
|
+
qti-gap-match-interaction qti-gap-text:is(:state(placeholder), [data-state~='placeholder']) {
|
|
3422
3408
|
/* The hole a spent/lifted chip leaves. Like the chip (see `drag`), it sets NO fill / border /
|
|
3423
3409
|
shadow of its own — those inherit from the resting chip (neutral by default, the brand's fill
|
|
3424
3410
|
when an overlay is on), so a brand can restyle the hole via a `:state(placeholder)` overlay
|
|
@@ -3429,7 +3415,7 @@
|
|
|
3429
3415
|
pointer-events: none;
|
|
3430
3416
|
}
|
|
3431
3417
|
|
|
3432
|
-
qti-gap-match-interaction qti-gap-text:state(dragging) {
|
|
3418
|
+
qti-gap-match-interaction qti-gap-text:is(:state(dragging), [data-state~='dragging']) {
|
|
3433
3419
|
/* The hole a spent/lifted chip leaves. Like the chip (see `drag`), it sets NO fill / border /
|
|
3434
3420
|
shadow of its own — those inherit from the resting chip (neutral by default, the brand's fill
|
|
3435
3421
|
when an overlay is on), so a brand can restyle the hole via a `:state(placeholder)` overlay
|
|
@@ -3443,21 +3429,22 @@
|
|
|
3443
3429
|
pointer-events: none;
|
|
3444
3430
|
}
|
|
3445
3431
|
|
|
3446
|
-
qti-gap-match-interaction qti-gap-text:state(return-anchor) {
|
|
3432
|
+
qti-gap-match-interaction qti-gap-text:is(:state(return-anchor), [data-state~='return-anchor']) {
|
|
3447
3433
|
border-color: var(--qti-drop-highlight-border-color);
|
|
3448
3434
|
box-shadow: inset 0 0 0 var(--qti-drop-highlight-border-width, 2px)
|
|
3449
3435
|
color-mix(in srgb, var(--qti-drop-highlight-border-color) 55%, transparent);
|
|
3450
3436
|
}
|
|
3451
3437
|
|
|
3452
|
-
qti-gap-match-interaction qti-gap:state(hover),
|
|
3453
|
-
qti-gap-match-interaction qti-gap:state(active) {
|
|
3438
|
+
qti-gap-match-interaction qti-gap:is(:state(hover), [data-state~='hover']),
|
|
3439
|
+
qti-gap-match-interaction qti-gap:is(:state(active), [data-state~='active']) {
|
|
3454
3440
|
background-color: var(--qti-drop-highlight-bg);
|
|
3455
3441
|
}
|
|
3456
3442
|
|
|
3457
|
-
qti-gap-match-interaction qti-gap:state(enabled) {
|
|
3443
|
+
qti-gap-match-interaction qti-gap:is(:state(enabled), [data-state~='enabled']) {
|
|
3458
3444
|
background-color: var(--qti-drop-highlight-enabled-bg);
|
|
3459
3445
|
}
|
|
3460
3446
|
}
|
|
3447
|
+
|
|
3461
3448
|
@layer qti-components.interactions.corrections {
|
|
3462
3449
|
/* A corrected chip — in the bank, and where it landed. Moved here from the shared
|
|
3463
3450
|
qti-corrections.css, which claimed `:state(drag)` for EVERY interaction in one unscoped rule:
|
|
@@ -3470,16 +3457,16 @@
|
|
|
3470
3457
|
DIRECTLY, which outranks the paint binding that reads --drag-background-color, so the solid fill
|
|
3471
3458
|
they asked for never rendered — a corrected gap-text has always been the pale tint. Left in place
|
|
3472
3459
|
they would have come alive the moment the shared rule left, and turned solid. */
|
|
3473
|
-
qti-gap-match-interaction :state(drag):state(candidate-correct),
|
|
3474
|
-
qti-gap::part(drag):state(candidate-correct) {
|
|
3460
|
+
qti-gap-match-interaction :is(:state(drag), [data-state~='drag']):is(:state(candidate-correct), [data-state~='candidate-correct']),
|
|
3461
|
+
qti-gap::part(drag):is(:state(candidate-correct), [data-state~='candidate-correct']) {
|
|
3475
3462
|
--drag-background-color: var(--qti-correct-light);
|
|
3476
3463
|
--drag-color: var(--qti-correct);
|
|
3477
3464
|
--drag-border-color: var(--qti-correct);
|
|
3478
3465
|
--drag-box-shadow: none;
|
|
3479
3466
|
}
|
|
3480
3467
|
|
|
3481
|
-
qti-gap-match-interaction :state(drag):state(candidate-incorrect),
|
|
3482
|
-
qti-gap::part(drag):state(candidate-incorrect) {
|
|
3468
|
+
qti-gap-match-interaction :is(:state(drag), [data-state~='drag']):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']),
|
|
3469
|
+
qti-gap::part(drag):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']) {
|
|
3483
3470
|
--drag-background-color: var(--qti-incorrect-light);
|
|
3484
3471
|
--drag-color: var(--qti-incorrect);
|
|
3485
3472
|
--drag-border-color: var(--qti-incorrect);
|
|
@@ -3489,6 +3476,7 @@
|
|
|
3489
3476
|
/* The bank is hidden by the interaction itself, on :host([answer-key]) — see
|
|
3490
3477
|
qti-gap-match-interaction.styles.ts. */
|
|
3491
3478
|
}
|
|
3479
|
+
|
|
3492
3480
|
/*
|
|
3493
3481
|
* A hotspot is indicated by a RING, not a fill — matching QTI 3's own figures (Impl-Guide Fig
|
|
3494
3482
|
* 54/55) and its shared-vocab wording ("selection lines and fills", the line being the ring).
|
|
@@ -3560,17 +3548,18 @@
|
|
|
3560
3548
|
outline-offset: 2px;
|
|
3561
3549
|
}
|
|
3562
3550
|
}
|
|
3551
|
+
|
|
3563
3552
|
@layer qti-components.interactions.states {
|
|
3564
3553
|
/*
|
|
3565
3554
|
* Selected: a bold, saturated ring — the Fig-54 weight jump. Same var, so poly and box shapes
|
|
3566
3555
|
* move together; poly additionally swaps to the bold outline mask.
|
|
3567
3556
|
*/
|
|
3568
|
-
qti-hotspot-interaction qti-hotspot-choice:state(checked) {
|
|
3557
|
+
qti-hotspot-interaction qti-hotspot-choice:is(:state(checked), [data-state~='checked']) {
|
|
3569
3558
|
--hs-ring: var(--qti-hotspot-ring-color, var(--qti-selected-bg));
|
|
3570
3559
|
--hs-width: calc(var(--qti-hotspot-ring-width, 2px) * 2);
|
|
3571
3560
|
}
|
|
3572
3561
|
|
|
3573
|
-
qti-hotspot-interaction qti-hotspot-choice[shape='poly']:state(checked) {
|
|
3562
|
+
qti-hotspot-interaction qti-hotspot-choice[shape='poly']:is(:state(checked), [data-state~='checked']) {
|
|
3574
3563
|
mask-image: var(--qti-shape-outline-bold);
|
|
3575
3564
|
-webkit-mask-image: var(--qti-shape-outline-bold);
|
|
3576
3565
|
}
|
|
@@ -3604,35 +3593,36 @@
|
|
|
3604
3593
|
* In `states` so it outranks the base ring and the `:hover` strengthen: hover must NOT reveal, or
|
|
3605
3594
|
* sweeping the pointer hands back the answer regions one at a time.
|
|
3606
3595
|
*/
|
|
3607
|
-
qti-hotspot-interaction.qti-unselected-hidden qti-hotspot-choice:not(:state(checked)):not(:focus-visible) {
|
|
3596
|
+
qti-hotspot-interaction.qti-unselected-hidden qti-hotspot-choice:not(:is(:state(checked), [data-state~='checked'])):not(:focus-visible) {
|
|
3608
3597
|
--hs-ring: transparent;
|
|
3609
3598
|
--hs-halo: transparent;
|
|
3610
3599
|
}
|
|
3611
3600
|
|
|
3612
|
-
qti-hotspot-interaction qti-hotspot-choice:state(disabled),
|
|
3613
|
-
qti-hotspot-interaction qti-hotspot-choice:state(readonly) {
|
|
3601
|
+
qti-hotspot-interaction qti-hotspot-choice:is(:state(disabled), [data-state~='disabled']),
|
|
3602
|
+
qti-hotspot-interaction qti-hotspot-choice:is(:state(readonly), [data-state~='readonly']) {
|
|
3614
3603
|
cursor: not-allowed;
|
|
3615
3604
|
pointer-events: none;
|
|
3616
3605
|
}
|
|
3617
3606
|
}
|
|
3607
|
+
|
|
3618
3608
|
@layer qti-components.interactions.corrections {
|
|
3619
3609
|
/*
|
|
3620
3610
|
* Correction and answer-key views recolour the same ring — one var, so circle and poly stay in
|
|
3621
3611
|
* step. Answer-key first, so a candidate's own judgement wins when both are present.
|
|
3622
3612
|
*/
|
|
3623
|
-
qti-hotspot-interaction qti-hotspot-choice:state(correct-response) {
|
|
3613
|
+
qti-hotspot-interaction qti-hotspot-choice:is(:state(correct-response), [data-state~='correct-response']) {
|
|
3624
3614
|
--qti-hotspot-ring-color: var(--qti-answer-border);
|
|
3625
3615
|
}
|
|
3626
3616
|
|
|
3627
|
-
qti-hotspot-interaction qti-hotspot-choice:state(candidate-correct) {
|
|
3617
|
+
qti-hotspot-interaction qti-hotspot-choice:is(:state(candidate-correct), [data-state~='candidate-correct']) {
|
|
3628
3618
|
--qti-hotspot-ring-color: var(--qti-correct);
|
|
3629
3619
|
}
|
|
3630
3620
|
|
|
3631
|
-
qti-hotspot-interaction qti-hotspot-choice:state(candidate-incorrect) {
|
|
3621
|
+
qti-hotspot-interaction qti-hotspot-choice:is(:state(candidate-incorrect), [data-state~='candidate-incorrect']) {
|
|
3632
3622
|
--qti-hotspot-ring-color: var(--qti-incorrect);
|
|
3633
3623
|
}
|
|
3634
3624
|
|
|
3635
|
-
.full-correct-response qti-hotspot-interaction qti-hotspot-choice:state(checked) {
|
|
3625
|
+
.full-correct-response qti-hotspot-interaction qti-hotspot-choice:is(:state(checked), [data-state~='checked']) {
|
|
3636
3626
|
--qti-hotspot-ring-color: var(--qti-answer-border);
|
|
3637
3627
|
}
|
|
3638
3628
|
|
|
@@ -3642,22 +3632,23 @@
|
|
|
3642
3632
|
* candidate-* hotspot is usually also :state(checked) and would be bold anyway; correct-response
|
|
3643
3633
|
* on an unselected region is the case this covers.)
|
|
3644
3634
|
*/
|
|
3645
|
-
qti-hotspot-interaction qti-hotspot-choice:state(correct-response),
|
|
3646
|
-
qti-hotspot-interaction qti-hotspot-choice:state(candidate-correct),
|
|
3647
|
-
qti-hotspot-interaction qti-hotspot-choice:state(candidate-incorrect),
|
|
3648
|
-
.full-correct-response qti-hotspot-interaction qti-hotspot-choice:state(checked) {
|
|
3635
|
+
qti-hotspot-interaction qti-hotspot-choice:is(:state(correct-response), [data-state~='correct-response']),
|
|
3636
|
+
qti-hotspot-interaction qti-hotspot-choice:is(:state(candidate-correct), [data-state~='candidate-correct']),
|
|
3637
|
+
qti-hotspot-interaction qti-hotspot-choice:is(:state(candidate-incorrect), [data-state~='candidate-incorrect']),
|
|
3638
|
+
.full-correct-response qti-hotspot-interaction qti-hotspot-choice:is(:state(checked), [data-state~='checked']) {
|
|
3649
3639
|
--hs-ring: var(--qti-hotspot-ring-color);
|
|
3650
3640
|
--hs-width: calc(var(--qti-hotspot-ring-width, 2px) * 2);
|
|
3651
3641
|
}
|
|
3652
3642
|
|
|
3653
|
-
qti-hotspot-interaction qti-hotspot-choice[shape='poly']:state(correct-response),
|
|
3654
|
-
qti-hotspot-interaction qti-hotspot-choice[shape='poly']:state(candidate-correct),
|
|
3655
|
-
qti-hotspot-interaction qti-hotspot-choice[shape='poly']:state(candidate-incorrect),
|
|
3656
|
-
.full-correct-response qti-hotspot-interaction qti-hotspot-choice[shape='poly']:state(checked) {
|
|
3643
|
+
qti-hotspot-interaction qti-hotspot-choice[shape='poly']:is(:state(correct-response), [data-state~='correct-response']),
|
|
3644
|
+
qti-hotspot-interaction qti-hotspot-choice[shape='poly']:is(:state(candidate-correct), [data-state~='candidate-correct']),
|
|
3645
|
+
qti-hotspot-interaction qti-hotspot-choice[shape='poly']:is(:state(candidate-incorrect), [data-state~='candidate-incorrect']),
|
|
3646
|
+
.full-correct-response qti-hotspot-interaction qti-hotspot-choice[shape='poly']:is(:state(checked), [data-state~='checked']) {
|
|
3657
3647
|
mask-image: var(--qti-shape-outline-bold);
|
|
3658
3648
|
-webkit-mask-image: var(--qti-shape-outline-bold);
|
|
3659
3649
|
}
|
|
3660
3650
|
}
|
|
3651
|
+
|
|
3661
3652
|
@layer qti-components.interactions.base {
|
|
3662
3653
|
qti-hottext-interaction {
|
|
3663
3654
|
--qti-hottext-selected-padding: var(--qti-padding-inline);
|
|
@@ -3678,118 +3669,91 @@
|
|
|
3678
3669
|
* target's active border: pay the space once, up front, so the state has only to repaint. Every
|
|
3679
3670
|
* hottext is now the size a selected one used to be, which is also a larger target to click.
|
|
3680
3671
|
*/
|
|
3681
|
-
|
|
3672
|
+
}
|
|
3673
|
+
qti-hottext-interaction qti-hottext {
|
|
3682
3674
|
padding: var(--qti-hottext-selected-padding);
|
|
3683
3675
|
}
|
|
3684
|
-
|
|
3685
|
-
&.qti-input-control-hidden {
|
|
3686
|
-
qti-hottext {
|
|
3676
|
+
qti-hottext-interaction.qti-input-control-hidden qti-hottext {
|
|
3687
3677
|
border: var(--qti-border);
|
|
3688
3678
|
border-radius: var(--qti-border-radius);
|
|
3689
3679
|
|
|
3690
3680
|
background: var(--qti-bg);
|
|
3681
|
+
}
|
|
3691
3682
|
|
|
3692
3683
|
|
|
3693
|
-
|
|
3684
|
+
:is(qti-hottext-interaction.qti-input-control-hidden qti-hottext):focus {
|
|
3694
3685
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
3695
3686
|
}
|
|
3696
|
-
|
|
3697
|
-
}
|
|
3698
|
-
|
|
3699
|
-
&.qti-unselected-hidden {
|
|
3700
|
-
qti-hottext {
|
|
3687
|
+
qti-hottext-interaction.qti-unselected-hidden qti-hottext {
|
|
3701
3688
|
border: 0;
|
|
3702
3689
|
border-radius: var(--qti-border-radius);
|
|
3703
3690
|
background-color: transparent;
|
|
3704
3691
|
outline: none;
|
|
3705
3692
|
cursor: pointer;
|
|
3693
|
+
}
|
|
3706
3694
|
|
|
3707
3695
|
|
|
3708
|
-
|
|
3696
|
+
:is(qti-hottext-interaction.qti-unselected-hidden qti-hottext):focus {
|
|
3709
3697
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
3710
3698
|
}
|
|
3711
|
-
|
|
3712
|
-
}
|
|
3713
|
-
|
|
3714
|
-
&:not(.qti-input-control-hidden, .qti-unselected-hidden) {
|
|
3715
|
-
qti-hottext {
|
|
3699
|
+
qti-hottext-interaction:not(.qti-input-control-hidden,.qti-unselected-hidden) qti-hottext {
|
|
3716
3700
|
border: var(--qti-border);
|
|
3717
3701
|
border-radius: var(--qti-border-radius);
|
|
3702
|
+
}
|
|
3718
3703
|
|
|
3719
3704
|
|
|
3720
|
-
|
|
3705
|
+
:is(qti-hottext-interaction:not(.qti-input-control-hidden,.qti-unselected-hidden) qti-hottext):focus {
|
|
3721
3706
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
3722
3707
|
}
|
|
3723
|
-
}
|
|
3724
|
-
}
|
|
3725
|
-
}
|
|
3726
3708
|
}
|
|
3709
|
+
|
|
3727
3710
|
@layer qti-components.interactions.states {
|
|
3728
|
-
|
|
3729
|
-
&.qti-input-control-hidden qti-hottext {
|
|
3730
|
-
&:state(checked) {
|
|
3711
|
+
:is(qti-hottext-interaction.qti-input-control-hidden qti-hottext):is(:state(checked), [data-state~='checked']) {
|
|
3731
3712
|
border-color: var(--qti-border-active);
|
|
3732
3713
|
background-color: var(--qti-selected-bg);
|
|
3733
3714
|
color: var(--qti-selected-color);
|
|
3734
3715
|
}
|
|
3735
3716
|
|
|
3736
|
-
|
|
3717
|
+
:is(qti-hottext-interaction.qti-input-control-hidden qti-hottext):is(:state(readonly), [data-state~='readonly']) {
|
|
3737
3718
|
cursor: pointer;
|
|
3738
3719
|
}
|
|
3739
3720
|
|
|
3740
|
-
|
|
3721
|
+
:is(qti-hottext-interaction.qti-input-control-hidden qti-hottext):is(:state(disabled), [data-state~='disabled']) {
|
|
3741
3722
|
cursor: not-allowed;
|
|
3742
3723
|
}
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
&.qti-unselected-hidden qti-hottext,
|
|
3746
|
-
&:not(.qti-input-control-hidden, .qti-unselected-hidden) qti-hottext {
|
|
3747
|
-
&:state(checked) {
|
|
3724
|
+
:is(qti-hottext-interaction.qti-unselected-hidden qti-hottext,qti-hottext-interaction:not(.qti-input-control-hidden,.qti-unselected-hidden) qti-hottext):is(:state(checked), [data-state~='checked']) {
|
|
3748
3725
|
background-color: var(--qti-selected-bg);
|
|
3749
3726
|
color: var(--qti-selected-color);
|
|
3750
3727
|
}
|
|
3751
3728
|
|
|
3752
|
-
|
|
3729
|
+
:is(qti-hottext-interaction.qti-unselected-hidden qti-hottext,qti-hottext-interaction:not(.qti-input-control-hidden,.qti-unselected-hidden) qti-hottext):is(:state(readonly), [data-state~='readonly']) {
|
|
3753
3730
|
cursor: pointer;
|
|
3754
3731
|
}
|
|
3755
3732
|
|
|
3756
|
-
|
|
3733
|
+
:is(qti-hottext-interaction.qti-unselected-hidden qti-hottext,qti-hottext-interaction:not(.qti-input-control-hidden,.qti-unselected-hidden) qti-hottext):is(:state(disabled), [data-state~='disabled']) {
|
|
3757
3734
|
cursor: not-allowed;
|
|
3758
3735
|
}
|
|
3759
|
-
}
|
|
3760
|
-
}
|
|
3761
3736
|
}
|
|
3737
|
+
|
|
3762
3738
|
@layer qti-components.interactions.corrections {
|
|
3763
|
-
|
|
3764
|
-
qti-hottext {
|
|
3765
|
-
&:state(correct-response),
|
|
3766
|
-
&[data-correct-response='true'] {
|
|
3767
|
-
&::after {
|
|
3739
|
+
:is(:is(qti-hottext-interaction qti-hottext):is(:state(correct-response), [data-state~='correct-response']),[data-correct-response='true']:is(qti-hottext-interaction qti-hottext))::after {
|
|
3768
3740
|
content: '\02714';
|
|
3769
3741
|
color: var(--qti-correct);
|
|
3770
3742
|
}
|
|
3771
|
-
|
|
3772
|
-
}
|
|
3773
|
-
|
|
3774
|
-
&.qti-input-control-hidden qti-hottext {
|
|
3775
|
-
&:state(candidate-correct) {
|
|
3743
|
+
:is(qti-hottext-interaction.qti-input-control-hidden qti-hottext):is(:state(candidate-correct), [data-state~='candidate-correct']) {
|
|
3776
3744
|
background-color: var(--qti-correct-light);
|
|
3777
3745
|
color: var(--qti-correct);
|
|
3778
3746
|
border-color: var(--qti-correct);
|
|
3779
3747
|
box-shadow: none;
|
|
3780
3748
|
}
|
|
3781
3749
|
|
|
3782
|
-
|
|
3750
|
+
:is(qti-hottext-interaction.qti-input-control-hidden qti-hottext):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']) {
|
|
3783
3751
|
background-color: var(--qti-incorrect-light);
|
|
3784
3752
|
color: var(--qti-incorrect);
|
|
3785
3753
|
border-color: var(--qti-incorrect);
|
|
3786
3754
|
box-shadow: none;
|
|
3787
3755
|
}
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
&.qti-unselected-hidden qti-hottext,
|
|
3791
|
-
&:not(.qti-input-control-hidden, .qti-unselected-hidden) qti-hottext {
|
|
3792
|
-
&:state(candidate-correct) {
|
|
3756
|
+
:is(qti-hottext-interaction.qti-unselected-hidden qti-hottext,qti-hottext-interaction:not(.qti-input-control-hidden,.qti-unselected-hidden) qti-hottext):is(:state(candidate-correct), [data-state~='candidate-correct']) {
|
|
3793
3757
|
background-color: var(--qti-correct-light);
|
|
3794
3758
|
color: var(--qti-correct);
|
|
3795
3759
|
border-color: var(--qti-correct);
|
|
@@ -3797,21 +3761,19 @@
|
|
|
3797
3761
|
box-shadow: inset 0 0 0 var(--qti-border-thickness) var(--qti-correct);
|
|
3798
3762
|
}
|
|
3799
3763
|
|
|
3800
|
-
|
|
3764
|
+
:is(qti-hottext-interaction.qti-unselected-hidden qti-hottext,qti-hottext-interaction:not(.qti-input-control-hidden,.qti-unselected-hidden) qti-hottext):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']) {
|
|
3801
3765
|
background-color: var(--qti-incorrect-light);
|
|
3802
3766
|
color: var(--qti-incorrect);
|
|
3803
3767
|
border-color: var(--qti-incorrect);
|
|
3804
3768
|
box-shadow: none;
|
|
3805
3769
|
box-shadow: inset 0 0 0 var(--qti-border-thickness) var(--qti-incorrect);
|
|
3806
3770
|
}
|
|
3807
|
-
}
|
|
3808
|
-
}
|
|
3809
3771
|
|
|
3810
|
-
.full-correct-response qti-hottext-interaction.qti-input-control-hidden qti-hottext:state(checked),
|
|
3811
|
-
.full-correct-response qti-hottext-interaction.qti-unselected-hidden qti-hottext:state(checked),
|
|
3772
|
+
.full-correct-response qti-hottext-interaction.qti-input-control-hidden qti-hottext:is(:state(checked), [data-state~='checked']),
|
|
3773
|
+
.full-correct-response qti-hottext-interaction.qti-unselected-hidden qti-hottext:is(:state(checked), [data-state~='checked']),
|
|
3812
3774
|
.full-correct-response
|
|
3813
3775
|
qti-hottext-interaction:not(.qti-input-control-hidden, .qti-unselected-hidden)
|
|
3814
|
-
qti-hottext:state(checked) {
|
|
3776
|
+
qti-hottext:is(:state(checked), [data-state~='checked']) {
|
|
3815
3777
|
background-color: var(--qti-answer-bg);
|
|
3816
3778
|
color: var(--qti-answer-fg);
|
|
3817
3779
|
border-color: var(--qti-answer-border);
|
|
@@ -3822,7 +3784,8 @@
|
|
|
3822
3784
|
padding-inline-end: var(--qti-gap);
|
|
3823
3785
|
|
|
3824
3786
|
/* The icon must not become the inline-flex container's first baseline item. */
|
|
3825
|
-
|
|
3787
|
+
}
|
|
3788
|
+
:is(.full-correct-response qti-hottext-interaction.qti-input-control-hidden qti-hottext:is(:state(checked), [data-state~='checked']),.full-correct-response qti-hottext-interaction.qti-unselected-hidden qti-hottext:is(:state(checked), [data-state~='checked']),.full-correct-response qti-hottext-interaction:not(.qti-input-control-hidden,.qti-unselected-hidden) qti-hottext:is(:state(checked), [data-state~='checked']))::before {
|
|
3826
3789
|
content: '';
|
|
3827
3790
|
background-color: var(--qti-answer-fg);
|
|
3828
3791
|
mask: var(--qti-check-mask) no-repeat center / contain;
|
|
@@ -3836,8 +3799,8 @@
|
|
|
3836
3799
|
width: 1em;
|
|
3837
3800
|
height: 1em;
|
|
3838
3801
|
}
|
|
3839
|
-
}
|
|
3840
3802
|
}
|
|
3803
|
+
|
|
3841
3804
|
@layer qti-components.interactions.base {
|
|
3842
3805
|
qti-inline-choice-interaction {
|
|
3843
3806
|
/* ── Host: the closed combobox, painted through the paint contract so a brand can restyle the
|
|
@@ -3858,7 +3821,8 @@
|
|
|
3858
3821
|
--field-color: var(--qti-fg);
|
|
3859
3822
|
|
|
3860
3823
|
/* ── Trigger: transparent inside the field border ───────────────────────── */
|
|
3861
|
-
|
|
3824
|
+
}
|
|
3825
|
+
qti-inline-choice-interaction::part(trigger) {
|
|
3862
3826
|
padding: var(--qti-padding-box);
|
|
3863
3827
|
background: transparent;
|
|
3864
3828
|
border: none;
|
|
@@ -3868,27 +3832,25 @@
|
|
|
3868
3832
|
font-size: inherit;
|
|
3869
3833
|
}
|
|
3870
3834
|
|
|
3871
|
-
|
|
3835
|
+
qti-inline-choice-interaction::part(trigger):focus-visible {
|
|
3872
3836
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
3873
3837
|
outline: none;
|
|
3874
3838
|
}
|
|
3875
3839
|
|
|
3876
|
-
|
|
3877
|
-
&[disabled]::part(trigger) {
|
|
3840
|
+
qti-inline-choice-interaction:is(:state(disabled), [data-state~='disabled'])::part(trigger),qti-inline-choice-interaction[disabled]::part(trigger) {
|
|
3878
3841
|
cursor: not-allowed;
|
|
3879
3842
|
}
|
|
3880
3843
|
|
|
3881
|
-
|
|
3882
|
-
&[readonly]::part(trigger) {
|
|
3844
|
+
qti-inline-choice-interaction:is(:state(readonly), [data-state~='readonly'])::part(trigger),qti-inline-choice-interaction[readonly]::part(trigger) {
|
|
3883
3845
|
cursor: pointer;
|
|
3884
3846
|
}
|
|
3885
3847
|
|
|
3886
3848
|
/* ── Chevron icon: color only; transform/mask/size live in shadow DOM ────── */
|
|
3887
|
-
|
|
3849
|
+
qti-inline-choice-interaction::part(dropdown-icon) {
|
|
3888
3850
|
color: inherit;
|
|
3889
3851
|
}
|
|
3890
3852
|
|
|
3891
|
-
|
|
3853
|
+
qti-inline-choice-interaction::part(dropdown-icon-open) {
|
|
3892
3854
|
color: inherit;
|
|
3893
3855
|
}
|
|
3894
3856
|
|
|
@@ -3906,7 +3868,7 @@
|
|
|
3906
3868
|
* above it. Two spacing tokens for one box is the whole bug — the vocabulary says pick one and
|
|
3907
3869
|
* spend it whole (see the CONTRACT note on --qti-padding-box / -inline / --qti-gap).
|
|
3908
3870
|
*/
|
|
3909
|
-
|
|
3871
|
+
qti-inline-choice-interaction::part(menu) {
|
|
3910
3872
|
background-color: var(--menu-background-color, var(--qti-component-background-color));
|
|
3911
3873
|
background-image: var(--menu-background-image, var(--qti-component-background-image));
|
|
3912
3874
|
border-width: var(--menu-border-width, var(--qti-component-border-width));
|
|
@@ -3940,18 +3902,18 @@
|
|
|
3940
3902
|
* position-try fallback applied", so fixing that needs a signal from script, and it is not worth
|
|
3941
3903
|
* one for the rarer case.
|
|
3942
3904
|
*/
|
|
3943
|
-
|
|
3905
|
+
qti-inline-choice-interaction:is(:state(open), [data-state~='open']) {
|
|
3944
3906
|
border-end-start-radius: 0;
|
|
3945
3907
|
border-end-end-radius: 0;
|
|
3946
3908
|
}
|
|
3947
3909
|
|
|
3948
|
-
|
|
3910
|
+
qti-inline-choice-interaction::part(menu):popover-open {
|
|
3949
3911
|
border-start-start-radius: 0;
|
|
3950
3912
|
border-start-end-radius: 0;
|
|
3951
3913
|
}
|
|
3952
3914
|
|
|
3953
3915
|
/* ── Option rows ─────────────────────────────────────────────────────────── */
|
|
3954
|
-
|
|
3916
|
+
qti-inline-choice-interaction::part(option) {
|
|
3955
3917
|
padding: var(--qti-padding-box);
|
|
3956
3918
|
border: 0;
|
|
3957
3919
|
/* Square, because a row now spans the full width of the menu. The menu's own radius still
|
|
@@ -3962,19 +3924,19 @@
|
|
|
3962
3924
|
cursor: pointer;
|
|
3963
3925
|
}
|
|
3964
3926
|
|
|
3965
|
-
|
|
3927
|
+
qti-inline-choice-interaction::part(option):focus-visible {
|
|
3966
3928
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
3967
3929
|
outline: none;
|
|
3968
3930
|
}
|
|
3969
3931
|
|
|
3970
|
-
|
|
3932
|
+
qti-inline-choice-interaction::part(option-selected) {
|
|
3971
3933
|
background-color: var(--qti-bg-active);
|
|
3972
3934
|
}
|
|
3973
3935
|
|
|
3974
3936
|
/* ── Slotted qti-inline-choice elements (light DOM) ──────────────────────── */
|
|
3975
3937
|
/* The option row's own box — flex, centred, single-line, clipped — is in
|
|
3976
3938
|
qti-inline-choice.styles.ts. */
|
|
3977
|
-
|
|
3939
|
+
qti-inline-choice-interaction qti-inline-choice {
|
|
3978
3940
|
width: 100%;
|
|
3979
3941
|
box-sizing: border-box;
|
|
3980
3942
|
padding: var(--qti-padding-box);
|
|
@@ -3990,19 +3952,19 @@
|
|
|
3990
3952
|
text-overflow: ellipsis;
|
|
3991
3953
|
}
|
|
3992
3954
|
|
|
3993
|
-
|
|
3955
|
+
qti-inline-choice-interaction qti-inline-choice:focus-visible {
|
|
3994
3956
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
3995
3957
|
outline: none;
|
|
3996
3958
|
}
|
|
3997
3959
|
|
|
3998
|
-
|
|
3960
|
+
qti-inline-choice-interaction qti-inline-choice:is(:state(checked), [data-state~='checked']) {
|
|
3999
3961
|
background-color: var(--qti-bg-active);
|
|
4000
3962
|
}
|
|
4001
3963
|
|
|
4002
3964
|
/* ── Validation message: a warning box, painted through the contract. Its non-neutral bits
|
|
4003
3965
|
(fg text, amber-tinted fill, amber border) are --message-* overrides; width/style/radius
|
|
4004
3966
|
come from the defaults. ── */
|
|
4005
|
-
|
|
3967
|
+
qti-inline-choice-interaction::part(message) {
|
|
4006
3968
|
background-color: var(--message-background-color, var(--qti-component-background-color));
|
|
4007
3969
|
background-image: var(--message-background-image, var(--qti-component-background-image));
|
|
4008
3970
|
border-width: var(--message-border-width, var(--qti-component-border-width));
|
|
@@ -4018,8 +3980,8 @@
|
|
|
4018
3980
|
--message-border-color: var(--qti-warning);
|
|
4019
3981
|
padding: var(--qti-padding-box);
|
|
4020
3982
|
}
|
|
4021
|
-
}
|
|
4022
3983
|
}
|
|
3984
|
+
|
|
4023
3985
|
@layer qti-components.interactions.corrections {
|
|
4024
3986
|
/* The answer key, moved here from the shared qti-corrections.css: it names this interaction, so
|
|
4025
3987
|
this file owns it. */
|
|
@@ -4027,36 +3989,34 @@
|
|
|
4027
3989
|
background-color: var(--qti-answer-bg);
|
|
4028
3990
|
color: var(--qti-answer-fg);
|
|
4029
3991
|
border-color: var(--qti-answer-border);
|
|
3992
|
+
}
|
|
4030
3993
|
|
|
4031
|
-
|
|
3994
|
+
:is(.full-correct-response qti-inline-choice-interaction)::part(value) {
|
|
4032
3995
|
color: var(--qti-answer-fg);
|
|
4033
3996
|
}
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
qti-inline-choice-interaction {
|
|
4037
|
-
&:state(candidate-correct) {
|
|
3997
|
+
qti-inline-choice-interaction:is(:state(candidate-correct), [data-state~='candidate-correct']) {
|
|
4038
3998
|
--field-background-color: var(--qti-correct-light);
|
|
4039
3999
|
--field-color: var(--qti-correct);
|
|
4040
4000
|
--field-border-color: var(--qti-correct);
|
|
4041
4001
|
--field-box-shadow: none;
|
|
4002
|
+
}
|
|
4042
4003
|
|
|
4043
|
-
|
|
4004
|
+
qti-inline-choice-interaction:is(:state(candidate-correct), [data-state~='candidate-correct'])::part(trigger) {
|
|
4044
4005
|
background: transparent;
|
|
4045
4006
|
}
|
|
4046
|
-
}
|
|
4047
4007
|
|
|
4048
|
-
|
|
4008
|
+
qti-inline-choice-interaction:is(:state(candidate-incorrect), [data-state~='candidate-incorrect']) {
|
|
4049
4009
|
--field-background-color: var(--qti-incorrect-light);
|
|
4050
4010
|
--field-color: var(--qti-incorrect);
|
|
4051
4011
|
--field-border-color: var(--qti-incorrect);
|
|
4052
4012
|
--field-box-shadow: none;
|
|
4013
|
+
}
|
|
4053
4014
|
|
|
4054
|
-
|
|
4015
|
+
qti-inline-choice-interaction:is(:state(candidate-incorrect), [data-state~='candidate-incorrect'])::part(trigger) {
|
|
4055
4016
|
background: transparent;
|
|
4056
4017
|
}
|
|
4057
|
-
}
|
|
4058
|
-
}
|
|
4059
4018
|
}
|
|
4019
|
+
|
|
4060
4020
|
/* This interaction's chip vocabulary — the bank chip, the placed chip, and the floating clone. One
|
|
4061
4021
|
such block per drag-drop interaction, opt-in; graphic-gap-match deliberately declares none. See
|
|
4062
4022
|
qti-states.css. Kept in the `global` layer, where these rules used to live, so cascade position is
|
|
@@ -4073,7 +4033,7 @@
|
|
|
4073
4033
|
sat on document.body it was in a different tree from the adopted stylesheet, and nothing — no
|
|
4074
4034
|
part, no attribute — could style it. */
|
|
4075
4035
|
@layer qti-components.global {
|
|
4076
|
-
qti-match-interaction :state(drag),
|
|
4036
|
+
qti-match-interaction :is(:state(drag), [data-state~='drag']),
|
|
4077
4037
|
[data-drag-clone][data-drag-interaction='qti-match-interaction'] {
|
|
4078
4038
|
/* Structural — the load-bearing box, never state-switched (layout-invariance contract).
|
|
4079
4039
|
box-sizing is deliberate: the clone is appended to document.body outside reset.css's
|
|
@@ -4124,7 +4084,7 @@
|
|
|
4124
4084
|
filter: var(--drag-filter, var(--qti-component-filter));
|
|
4125
4085
|
}
|
|
4126
4086
|
|
|
4127
|
-
qti-match-interaction :state(drag)::part(control)::before,
|
|
4087
|
+
qti-match-interaction :is(:state(drag), [data-state~='drag'])::part(control)::before,
|
|
4128
4088
|
qti-match-interaction::part(drag-control)::before,
|
|
4129
4089
|
qti-match-interaction ::part(drag-control)::before,
|
|
4130
4090
|
[data-drag-clone][data-drag-interaction='qti-match-interaction']::part(control)::before {
|
|
@@ -4139,6 +4099,7 @@
|
|
|
4139
4099
|
-webkit-mask: var(--qti-grip-mask) no-repeat center / contain;
|
|
4140
4100
|
}
|
|
4141
4101
|
}
|
|
4102
|
+
|
|
4142
4103
|
@layer qti-components.interactions.base {
|
|
4143
4104
|
/* Editor fake-drag projected into the target choice's `drop` shadow.
|
|
4144
4105
|
Reuses the same `drag` styling so the editor preview matches what students
|
|
@@ -4191,19 +4152,19 @@
|
|
|
4191
4152
|
color: var(--drag-color, var(--qti-component-color));
|
|
4192
4153
|
opacity: var(--drag-opacity, var(--qti-component-opacity));
|
|
4193
4154
|
filter: var(--drag-filter, var(--qti-component-filter));
|
|
4194
|
-
|
|
4155
|
+
}
|
|
4195
4156
|
@media (hover: hover) {
|
|
4157
|
+
:is(qti-simple-associable-choice::part(drag)):hover {
|
|
4196
4158
|
background-color: color-mix(
|
|
4197
4159
|
in srgb,
|
|
4198
4160
|
var(--drag-background-color, var(--qti-component-background-color)) 92%,
|
|
4199
4161
|
black
|
|
4200
4162
|
);
|
|
4201
|
-
}
|
|
4202
4163
|
}
|
|
4203
|
-
|
|
4164
|
+
}
|
|
4165
|
+
:is(qti-simple-associable-choice::part(drag)):focus {
|
|
4204
4166
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
4205
4167
|
}
|
|
4206
|
-
}
|
|
4207
4168
|
|
|
4208
4169
|
qti-match-interaction:not(.qti-match-tabular) {
|
|
4209
4170
|
/*
|
|
@@ -4225,9 +4186,11 @@
|
|
|
4225
4186
|
|
|
4226
4187
|
/* The bank and the target grid are laid out in qti-match-interaction.styles.ts. Only the gaps
|
|
4227
4188
|
are still set here — gap is spacing. */
|
|
4228
|
-
|
|
4189
|
+
}
|
|
4190
|
+
qti-match-interaction:not(.qti-match-tabular) qti-simple-match-set:first-of-type {
|
|
4229
4191
|
gap: var(--qti-gap);
|
|
4230
|
-
|
|
4192
|
+
}
|
|
4193
|
+
:is(qti-match-interaction:not(.qti-match-tabular) qti-simple-match-set:first-of-type) qti-simple-associable-choice {
|
|
4231
4194
|
/* Structural — the load-bearing box, never state-switched (layout-invariance contract).
|
|
4232
4195
|
box-sizing is deliberate: the clone is appended to document.body outside reset.css's
|
|
4233
4196
|
@scope, so it inherits no border-box from anywhere else and this sets it. */
|
|
@@ -4275,44 +4238,41 @@
|
|
|
4275
4238
|
color: var(--drag-color, var(--qti-component-color));
|
|
4276
4239
|
opacity: var(--drag-opacity, var(--qti-component-opacity));
|
|
4277
4240
|
filter: var(--drag-filter, var(--qti-component-filter));
|
|
4278
|
-
|
|
4241
|
+
}
|
|
4242
|
+
[dragging]:is(:is(qti-match-interaction:not(.qti-match-tabular) qti-simple-match-set:first-of-type) qti-simple-associable-choice) {
|
|
4279
4243
|
pointer-events: none;
|
|
4280
4244
|
rotate: -2deg;
|
|
4281
4245
|
--drag-box-shadow: 0 8px 12px rgb(0 0 0 / 20%), 0 4px 8px rgb(0 0 0 / 10%);
|
|
4282
4246
|
}
|
|
4283
|
-
&:hover {
|
|
4284
4247
|
@media (hover: hover) {
|
|
4248
|
+
:is(:is(qti-match-interaction:not(.qti-match-tabular) qti-simple-match-set:first-of-type) qti-simple-associable-choice):hover {
|
|
4285
4249
|
background-color: color-mix(
|
|
4286
4250
|
in srgb,
|
|
4287
4251
|
var(--drag-background-color, var(--qti-component-background-color)) 92%,
|
|
4288
4252
|
black
|
|
4289
4253
|
);
|
|
4290
|
-
}
|
|
4291
4254
|
}
|
|
4292
|
-
|
|
4255
|
+
}
|
|
4256
|
+
:is(:is(qti-match-interaction:not(.qti-match-tabular) qti-simple-match-set:first-of-type) qti-simple-associable-choice):focus {
|
|
4293
4257
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
4294
4258
|
}
|
|
4295
|
-
|
|
4296
|
-
}
|
|
4297
|
-
& qti-simple-match-set:last-of-type {
|
|
4259
|
+
qti-match-interaction:not(.qti-match-tabular) qti-simple-match-set:last-of-type {
|
|
4298
4260
|
gap: var(--qti-gap);
|
|
4299
|
-
|
|
4300
|
-
|
|
4261
|
+
}
|
|
4262
|
+
:is(:is(qti-match-interaction:not(.qti-match-tabular) qti-simple-match-set:last-of-type) > qti-simple-associable-choice) img {
|
|
4301
4263
|
max-width: 100%;
|
|
4302
4264
|
height: auto;
|
|
4303
4265
|
}
|
|
4304
|
-
|
|
4305
|
-
&::part(drop) {
|
|
4266
|
+
[disabled]:is(:is(qti-match-interaction:not(.qti-match-tabular) qti-simple-match-set:last-of-type) > qti-simple-associable-choice)::part(drop) {
|
|
4306
4267
|
cursor: not-allowed;
|
|
4307
4268
|
}
|
|
4308
|
-
}
|
|
4309
4269
|
/*
|
|
4310
4270
|
* No `[active]` highlight. Lifting a chip used to draw a solid `--qti-border-active` border
|
|
4311
4271
|
* around every drop container at once, which says "any of these" — the least useful thing to
|
|
4312
4272
|
* say. What the candidate wants to see is the hole the chip left, and that is painted on the
|
|
4313
4273
|
* chip's own `:state(dragging)` / `:state(placeholder)`.
|
|
4314
4274
|
*/
|
|
4315
|
-
|
|
4275
|
+
:is(:is(qti-match-interaction:not(.qti-match-tabular) qti-simple-match-set:last-of-type) > qti-simple-associable-choice)::part(drop) {
|
|
4316
4276
|
background-color: var(--drop-background-color, var(--qti-component-background-color));
|
|
4317
4277
|
background-image: var(--drop-background-image, var(--qti-component-background-image));
|
|
4318
4278
|
border-width: var(--drop-border-width, var(--qti-component-border-width));
|
|
@@ -4330,20 +4290,22 @@
|
|
|
4330
4290
|
used to LEAK: `dragging` sets --component-box-shadow, one shared namespace, so it
|
|
4331
4291
|
inherited onto every chip nested in the drop. That half is now structural — `dragging`
|
|
4332
4292
|
sets --drag-box-shadow, which a drop does not read.) */
|
|
4333
|
-
|
|
4293
|
+
}
|
|
4294
|
+
:is(:is(:is(qti-match-interaction:not(.qti-match-tabular) qti-simple-match-set:last-of-type) > qti-simple-associable-choice)::part(drop)):focus {
|
|
4334
4295
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
4335
4296
|
}
|
|
4297
|
+
:is(:is(qti-match-interaction:not(.qti-match-tabular) qti-simple-match-set:last-of-type) > qti-simple-associable-choice)::part(drop) {
|
|
4336
4298
|
margin-top: var(--qti-gap);
|
|
4337
4299
|
gap: var(--qti-gap);
|
|
4338
4300
|
}
|
|
4339
|
-
|
|
4301
|
+
:is(:is(qti-match-interaction:not(.qti-match-tabular) qti-simple-match-set:last-of-type) > qti-simple-associable-choice) > *:not(qti-simple-associable-choice) {
|
|
4340
4302
|
pointer-events: none;
|
|
4341
4303
|
}
|
|
4342
4304
|
/* A chip nested in a drop target renders no drop region of its own. That is the component's
|
|
4343
4305
|
own rule — qti-simple-associable-choice.styles.ts hides [part~='drop'] for both
|
|
4344
4306
|
:host(:state(drag)) and :host([part~='drag']), which covers the placed clone this
|
|
4345
4307
|
selector could not reach. */
|
|
4346
|
-
|
|
4308
|
+
:is(:is(qti-match-interaction:not(.qti-match-tabular) qti-simple-match-set:last-of-type) > qti-simple-associable-choice) > qti-simple-associable-choice {
|
|
4347
4309
|
/* Structural — the load-bearing box, never state-switched (layout-invariance contract).
|
|
4348
4310
|
box-sizing is deliberate: the clone is appended to document.body outside reset.css's
|
|
4349
4311
|
@scope, so it inherits no border-box from anywhere else and this sets it. */
|
|
@@ -4391,26 +4353,23 @@
|
|
|
4391
4353
|
color: var(--drag-color, var(--qti-component-color));
|
|
4392
4354
|
opacity: var(--drag-opacity, var(--qti-component-opacity));
|
|
4393
4355
|
filter: var(--drag-filter, var(--qti-component-filter));
|
|
4394
|
-
|
|
4356
|
+
}
|
|
4395
4357
|
@media (hover: hover) {
|
|
4358
|
+
:is(:is(:is(qti-match-interaction:not(.qti-match-tabular) qti-simple-match-set:last-of-type) > qti-simple-associable-choice) > qti-simple-associable-choice):hover {
|
|
4396
4359
|
background-color: color-mix(
|
|
4397
4360
|
in srgb,
|
|
4398
4361
|
var(--drag-background-color, var(--qti-component-background-color)) 92%,
|
|
4399
4362
|
black
|
|
4400
4363
|
);
|
|
4401
|
-
}
|
|
4402
4364
|
}
|
|
4403
|
-
|
|
4365
|
+
}
|
|
4366
|
+
:is(:is(:is(qti-match-interaction:not(.qti-match-tabular) qti-simple-match-set:last-of-type) > qti-simple-associable-choice) > qti-simple-associable-choice):focus {
|
|
4404
4367
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
4405
4368
|
}
|
|
4406
|
-
}
|
|
4407
|
-
}
|
|
4408
|
-
}
|
|
4409
|
-
}
|
|
4410
4369
|
|
|
4411
4370
|
qti-match-interaction:not(.qti-match-tabular)
|
|
4412
4371
|
qti-simple-match-set:first-of-type
|
|
4413
|
-
qti-simple-associable-choice:state(drag),
|
|
4372
|
+
qti-simple-associable-choice:is(:state(drag), [data-state~='drag']),
|
|
4414
4373
|
qti-match-interaction:not(.qti-match-tabular) qti-simple-associable-choice::part(drag) {
|
|
4415
4374
|
/* Structural — the load-bearing box, never state-switched (layout-invariance contract).
|
|
4416
4375
|
box-sizing is deliberate: the clone is appended to document.body outside reset.css's
|
|
@@ -4460,35 +4419,32 @@
|
|
|
4460
4419
|
opacity: var(--drag-opacity, var(--qti-component-opacity));
|
|
4461
4420
|
filter: var(--drag-filter, var(--qti-component-filter));
|
|
4462
4421
|
}
|
|
4463
|
-
|
|
4464
|
-
qti-match-interaction:not(.qti-match-tabular) qti-simple-match-set:last-of-type > qti-simple-associable-choice {
|
|
4465
4422
|
/* The label's `align-content` and the drop's `flex-grow` are the target card's own box, and live
|
|
4466
4423
|
in qti-simple-associable-choice.styles.ts under :host(:state(droppable)). `box-sizing` went with
|
|
4467
4424
|
them: border-box is already the reset, and content-box is what dropRegion sets. */
|
|
4468
|
-
|
|
4425
|
+
:is(qti-match-interaction:not(.qti-match-tabular) qti-simple-match-set:last-of-type > qti-simple-associable-choice)::part(label) {
|
|
4469
4426
|
border: var(--qti-border);
|
|
4470
4427
|
border-top-left-radius: var(--qti-border-radius);
|
|
4471
4428
|
border-top-right-radius: var(--qti-border-radius);
|
|
4472
4429
|
padding: 0.5rem;
|
|
4473
4430
|
}
|
|
4474
4431
|
|
|
4475
|
-
|
|
4432
|
+
:is(qti-match-interaction:not(.qti-match-tabular) qti-simple-match-set:last-of-type > qti-simple-associable-choice)::part(drop) {
|
|
4476
4433
|
margin-top: 0;
|
|
4477
4434
|
border-top: none;
|
|
4478
4435
|
border-top-left-radius: 0;
|
|
4479
4436
|
border-top-right-radius: 0;
|
|
4480
4437
|
background: none;
|
|
4481
4438
|
}
|
|
4482
|
-
|
|
4483
|
-
}
|
|
4484
4439
|
}
|
|
4440
|
+
|
|
4485
4441
|
@layer qti-components.interactions.states {
|
|
4486
4442
|
qti-match-interaction:not(.qti-match-tabular)
|
|
4487
4443
|
qti-simple-match-set:first-of-type
|
|
4488
|
-
qti-simple-associable-choice:state(dragging),
|
|
4444
|
+
qti-simple-associable-choice:is(:state(dragging), [data-state~='dragging']),
|
|
4489
4445
|
qti-match-interaction:not(.qti-match-tabular)
|
|
4490
4446
|
qti-simple-match-set:first-of-type
|
|
4491
|
-
qti-simple-associable-choice:state(placeholder) {
|
|
4447
|
+
qti-simple-associable-choice:is(:state(placeholder), [data-state~='placeholder']) {
|
|
4492
4448
|
/* The hole a spent/lifted chip leaves. Like the chip (see `drag`), it sets NO fill / border /
|
|
4493
4449
|
shadow of its own — those inherit from the resting chip (neutral by default, the brand's fill
|
|
4494
4450
|
when an overlay is on), so a brand can restyle the hole via a `:state(placeholder)` overlay
|
|
@@ -4501,42 +4457,42 @@
|
|
|
4501
4457
|
|
|
4502
4458
|
qti-match-interaction:not(.qti-match-tabular)
|
|
4503
4459
|
qti-simple-match-set:first-of-type
|
|
4504
|
-
qti-simple-associable-choice:state(dragging)
|
|
4460
|
+
qti-simple-associable-choice:is(:state(dragging), [data-state~='dragging'])
|
|
4505
4461
|
> *,
|
|
4506
4462
|
qti-match-interaction:not(.qti-match-tabular)
|
|
4507
4463
|
qti-simple-match-set:first-of-type
|
|
4508
|
-
qti-simple-associable-choice:state(placeholder)
|
|
4464
|
+
qti-simple-associable-choice:is(:state(placeholder), [data-state~='placeholder'])
|
|
4509
4465
|
> * {
|
|
4510
4466
|
visibility: hidden;
|
|
4511
4467
|
}
|
|
4512
4468
|
|
|
4513
4469
|
qti-match-interaction:not(.qti-match-tabular)
|
|
4514
4470
|
qti-simple-match-set:first-of-type
|
|
4515
|
-
qti-simple-associable-choice:state(dragging)::part(label),
|
|
4471
|
+
qti-simple-associable-choice:is(:state(dragging), [data-state~='dragging'])::part(label),
|
|
4516
4472
|
qti-match-interaction:not(.qti-match-tabular)
|
|
4517
4473
|
qti-simple-match-set:first-of-type
|
|
4518
|
-
qti-simple-associable-choice:state(placeholder)::part(label) {
|
|
4474
|
+
qti-simple-associable-choice:is(:state(placeholder), [data-state~='placeholder'])::part(label) {
|
|
4519
4475
|
visibility: hidden;
|
|
4520
4476
|
}
|
|
4521
4477
|
|
|
4522
4478
|
qti-match-interaction:not(.qti-match-tabular)
|
|
4523
4479
|
qti-simple-match-set:last-of-type
|
|
4524
|
-
> qti-simple-associable-choice:state(hover)::part(drop),
|
|
4480
|
+
> qti-simple-associable-choice:is(:state(hover), [data-state~='hover'])::part(drop),
|
|
4525
4481
|
qti-match-interaction:not(.qti-match-tabular)
|
|
4526
4482
|
qti-simple-match-set:last-of-type
|
|
4527
|
-
> qti-simple-associable-choice:state(active)::part(drop) {
|
|
4483
|
+
> qti-simple-associable-choice:is(:state(active), [data-state~='active'])::part(drop) {
|
|
4528
4484
|
background-color: var(--qti-drop-highlight-bg);
|
|
4529
4485
|
}
|
|
4530
4486
|
|
|
4531
4487
|
qti-match-interaction:not(.qti-match-tabular)
|
|
4532
4488
|
qti-simple-match-set:last-of-type
|
|
4533
|
-
> qti-simple-associable-choice:state(enabled)::part(drop) {
|
|
4489
|
+
> qti-simple-associable-choice:is(:state(enabled), [data-state~='enabled'])::part(drop) {
|
|
4534
4490
|
background-color: var(--qti-drop-highlight-enabled-bg);
|
|
4535
4491
|
}
|
|
4536
4492
|
|
|
4537
4493
|
qti-match-interaction:not(.qti-match-tabular)
|
|
4538
4494
|
qti-simple-match-set:first-of-type
|
|
4539
|
-
qti-simple-associable-choice:state(dragging) {
|
|
4495
|
+
qti-simple-associable-choice:is(:state(dragging), [data-state~='dragging']) {
|
|
4540
4496
|
border-color: var(--qti-drop-highlight-border-color);
|
|
4541
4497
|
box-shadow: inset 0 0 0 var(--qti-drop-highlight-border-width, 2px)
|
|
4542
4498
|
color-mix(in srgb, var(--qti-drop-highlight-border-color) 55%, transparent);
|
|
@@ -4544,12 +4500,13 @@
|
|
|
4544
4500
|
|
|
4545
4501
|
qti-match-interaction:not(.qti-match-tabular)
|
|
4546
4502
|
qti-simple-match-set:first-of-type
|
|
4547
|
-
qti-simple-associable-choice:state(return-anchor) {
|
|
4503
|
+
qti-simple-associable-choice:is(:state(return-anchor), [data-state~='return-anchor']) {
|
|
4548
4504
|
border-color: var(--qti-drop-highlight-border-color);
|
|
4549
4505
|
box-shadow: inset 0 0 0 var(--qti-drop-highlight-border-width, 2px)
|
|
4550
4506
|
color-mix(in srgb, var(--qti-drop-highlight-border-color) 55%, transparent);
|
|
4551
4507
|
}
|
|
4552
4508
|
}
|
|
4509
|
+
|
|
4553
4510
|
@layer qti-components.interactions.corrections {
|
|
4554
4511
|
/* A corrected chip — in the bank, and where it landed. Moved here from the shared
|
|
4555
4512
|
qti-corrections.css, which claimed `:state(drag)` for EVERY interaction in one unscoped rule:
|
|
@@ -4561,16 +4518,16 @@
|
|
|
4561
4518
|
same reason as gap-match's: the shared rule's DIRECT `background-color` outranked the binding
|
|
4562
4519
|
that reads them, so their solid fill never rendered. They out-specify this block, so leaving them
|
|
4563
4520
|
would have flipped a corrected placed chip from the pale tint to solid. */
|
|
4564
|
-
qti-match-interaction:not(.qti-match-tabular) :state(drag):state(candidate-correct),
|
|
4565
|
-
qti-match-interaction:not(.qti-match-tabular) qti-simple-associable-choice::part(drag):state(candidate-correct) {
|
|
4521
|
+
qti-match-interaction:not(.qti-match-tabular) :is(:state(drag), [data-state~='drag']):is(:state(candidate-correct), [data-state~='candidate-correct']),
|
|
4522
|
+
qti-match-interaction:not(.qti-match-tabular) qti-simple-associable-choice::part(drag):is(:state(candidate-correct), [data-state~='candidate-correct']) {
|
|
4566
4523
|
--drag-background-color: var(--qti-correct-light);
|
|
4567
4524
|
--drag-color: var(--qti-correct);
|
|
4568
4525
|
--drag-border-color: var(--qti-correct);
|
|
4569
4526
|
--drag-box-shadow: none;
|
|
4570
4527
|
}
|
|
4571
4528
|
|
|
4572
|
-
qti-match-interaction:not(.qti-match-tabular) :state(drag):state(candidate-incorrect),
|
|
4573
|
-
qti-match-interaction:not(.qti-match-tabular) qti-simple-associable-choice::part(drag):state(candidate-incorrect) {
|
|
4529
|
+
qti-match-interaction:not(.qti-match-tabular) :is(:state(drag), [data-state~='drag']):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']),
|
|
4530
|
+
qti-match-interaction:not(.qti-match-tabular) qti-simple-associable-choice::part(drag):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']) {
|
|
4574
4531
|
--drag-background-color: var(--qti-incorrect-light);
|
|
4575
4532
|
--drag-color: var(--qti-incorrect);
|
|
4576
4533
|
--drag-border-color: var(--qti-incorrect);
|
|
@@ -4580,19 +4537,19 @@
|
|
|
4580
4537
|
/* The bank is hidden by the interaction itself, on :host([answer-key]) — see
|
|
4581
4538
|
qti-match-interaction.styles.ts. */
|
|
4582
4539
|
}
|
|
4540
|
+
|
|
4583
4541
|
@layer qti-components.interactions.base {
|
|
4584
|
-
|
|
4585
|
-
&::part(corner) {
|
|
4542
|
+
qti-match-interaction.qti-match-tabular::part(corner) {
|
|
4586
4543
|
border: var(--qti-border-thickness) var(--qti-border-style) var(--qti-border-color);
|
|
4587
4544
|
background-color: var(--qti-bg-active);
|
|
4588
4545
|
}
|
|
4589
4546
|
|
|
4590
|
-
|
|
4547
|
+
qti-match-interaction.qti-match-tabular::part(input-cell) {
|
|
4591
4548
|
border: var(--qti-border-thickness) var(--qti-border-style) var(--qti-border-color);
|
|
4592
4549
|
padding: var(--qti-padding-box);
|
|
4593
4550
|
transition: background-color 0.1s ease;
|
|
4594
4551
|
}
|
|
4595
|
-
|
|
4552
|
+
qti-match-interaction.qti-match-tabular::part(input-cell):hover {
|
|
4596
4553
|
background-color: var(--qti-bg-active);
|
|
4597
4554
|
}
|
|
4598
4555
|
|
|
@@ -4603,7 +4560,7 @@
|
|
|
4603
4560
|
ElementInternals and cannot carry `:state()` — and `::part(x):state(y)` needs the state on
|
|
4604
4561
|
the part's own element. They therefore carry variant *part tokens*, which deliberately
|
|
4605
4562
|
reuse the state vocabulary: radio | checkbox, checked, correct | incorrect. */
|
|
4606
|
-
|
|
4563
|
+
qti-match-interaction.qti-match-tabular::part(control radio) {
|
|
4607
4564
|
background-color: var(--radio-background-color, var(--qti-component-background-color));
|
|
4608
4565
|
background-image: var(--radio-background-image, var(--qti-component-background-image));
|
|
4609
4566
|
border-width: var(--radio-border-width, var(--qti-component-border-width));
|
|
@@ -4620,7 +4577,7 @@
|
|
|
4620
4577
|
edge, so a brand can square a radio off without having to out-specify this rule. */
|
|
4621
4578
|
border-radius: var(--radio-border-radius, 100%);
|
|
4622
4579
|
}
|
|
4623
|
-
|
|
4580
|
+
qti-match-interaction.qti-match-tabular::part(control checkbox) {
|
|
4624
4581
|
background-color: var(--checkbox-background-color, var(--qti-component-background-color));
|
|
4625
4582
|
background-image: var(--checkbox-background-image, var(--qti-component-background-image));
|
|
4626
4583
|
border-width: var(--checkbox-border-width, var(--qti-component-border-width));
|
|
@@ -4634,7 +4591,7 @@
|
|
|
4634
4591
|
width: var(--qti-control-size);
|
|
4635
4592
|
height: var(--qti-control-size);
|
|
4636
4593
|
}
|
|
4637
|
-
|
|
4594
|
+
qti-match-interaction.qti-match-tabular::part(control-mark) {
|
|
4638
4595
|
width: calc(var(--qti-control-size) * 0.625);
|
|
4639
4596
|
height: calc(var(--qti-control-size) * 0.625);
|
|
4640
4597
|
}
|
|
@@ -4642,19 +4599,18 @@
|
|
|
4642
4599
|
outer box and the inner indicator independently. Scope the base inner-fill rules to
|
|
4643
4600
|
`control-mark` so the classic dot-in-ring look stays intact; themes wanting the inverted
|
|
4644
4601
|
look (outer filled, e.g. Kennisnet) add their own `::part(control checked)` rules. */
|
|
4645
|
-
|
|
4602
|
+
qti-match-interaction.qti-match-tabular::part(control-mark radio checked) {
|
|
4646
4603
|
/* 0.5 reproduces today's 8px at the default 1rem — see mark-size for why this is a fraction. */
|
|
4647
4604
|
width: calc(var(--qti-control-size) * 0.5);
|
|
4648
4605
|
height: calc(var(--qti-control-size) * 0.5);
|
|
4649
4606
|
background-color: var(--radio-mark-color, white);
|
|
4650
4607
|
border-radius: 100%;
|
|
4651
4608
|
}
|
|
4652
|
-
|
|
4609
|
+
qti-match-interaction.qti-match-tabular::part(control-mark checkbox checked) {
|
|
4653
4610
|
background-color: var(--checkbox-mark-color, white);
|
|
4654
4611
|
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='currentColor' width='100%' height='100%' viewBox='0 0 24 24'%3E%3Cpath d='M20.285 2l-11.285 11.567-5.286-5.011-3.714 3.716 9 8.728 15-15.285z'/%3E%3C/svg%3E");
|
|
4655
4612
|
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='currentColor' width='100%' height='100%' viewBox='0 0 24 24'%3E%3Cpath d='M20.285 2l-11.285 11.567-5.286-5.011-3.714 3.716 9 8.728 15-15.285z'/%3E%3C/svg%3E");
|
|
4656
4613
|
}
|
|
4657
|
-
}
|
|
4658
4614
|
|
|
4659
4615
|
/* Header cells — the two slotted <qti-simple-match-set>s have display:contents
|
|
4660
4616
|
so their child choices act as row/column header cells. Written as a fully-
|
|
@@ -4684,79 +4640,71 @@
|
|
|
4684
4640
|
qti-match-interaction.qti-match-tabular qti-simple-match-set:last-of-type qti-simple-associable-choice {
|
|
4685
4641
|
text-align: center;
|
|
4686
4642
|
}
|
|
4687
|
-
|
|
4688
|
-
qti-match-interaction.qti-match-tabular {
|
|
4689
4643
|
/* The 1px gap is the grid's own background showing through, which is what draws the cell rules.
|
|
4690
4644
|
Clipping it to the rounded corners is layout and lives in qti-match-interaction-tabular.styles.ts. */
|
|
4691
|
-
|
|
4645
|
+
qti-match-interaction.qti-match-tabular::part(grid) {
|
|
4692
4646
|
gap: 1px;
|
|
4693
4647
|
background-color: var(--qti-border-color);
|
|
4694
4648
|
border: var(--qti-border-thickness) solid var(--qti-border-color);
|
|
4695
4649
|
border-radius: var(--qti-border-radius);
|
|
4696
4650
|
}
|
|
4697
4651
|
|
|
4698
|
-
|
|
4699
|
-
&::part(input-cell) {
|
|
4652
|
+
qti-match-interaction.qti-match-tabular::part(corner),qti-match-interaction.qti-match-tabular::part(input-cell) {
|
|
4700
4653
|
border: none;
|
|
4701
4654
|
background-color: white;
|
|
4702
4655
|
}
|
|
4703
4656
|
|
|
4704
|
-
|
|
4657
|
+
qti-match-interaction.qti-match-tabular::part(control checked) {
|
|
4705
4658
|
border-color: var(--qti-primary);
|
|
4706
4659
|
background-color: var(--qti-primary);
|
|
4707
4660
|
}
|
|
4708
4661
|
|
|
4709
|
-
|
|
4662
|
+
qti-match-interaction.qti-match-tabular::part(control-mark radio checked) {
|
|
4710
4663
|
background-color: white;
|
|
4711
4664
|
width: calc(var(--qti-control-size) * 0.5);
|
|
4712
4665
|
height: calc(var(--qti-control-size) * 0.5);
|
|
4713
4666
|
}
|
|
4714
4667
|
|
|
4715
|
-
|
|
4668
|
+
qti-match-interaction.qti-match-tabular::part(control-mark checkbox checked) {
|
|
4716
4669
|
background-color: white;
|
|
4717
4670
|
}
|
|
4718
|
-
}
|
|
4719
4671
|
|
|
4720
4672
|
qti-match-interaction.qti-match-tabular qti-simple-match-set qti-simple-associable-choice {
|
|
4721
4673
|
border: none;
|
|
4722
4674
|
background-color: white;
|
|
4723
4675
|
}
|
|
4724
4676
|
}
|
|
4677
|
+
|
|
4725
4678
|
@layer qti-components.interactions.corrections {
|
|
4726
|
-
qti-match-interaction.qti-match-tabular {
|
|
4727
4679
|
/* Correct / incorrect overlays — border on the outer box, and a matching fill on the inner
|
|
4728
4680
|
indicator when checked. */
|
|
4729
|
-
|
|
4681
|
+
qti-match-interaction.qti-match-tabular::part(control correct) {
|
|
4730
4682
|
border-color: var(--qti-correct);
|
|
4731
4683
|
}
|
|
4732
|
-
|
|
4684
|
+
qti-match-interaction.qti-match-tabular::part(control incorrect) {
|
|
4733
4685
|
border-color: var(--qti-incorrect);
|
|
4734
4686
|
}
|
|
4735
4687
|
|
|
4736
|
-
|
|
4688
|
+
qti-match-interaction.qti-match-tabular::part(control checked correct) {
|
|
4737
4689
|
border-color: var(--qti-correct);
|
|
4738
4690
|
background-color: var(--qti-correct);
|
|
4739
4691
|
}
|
|
4740
4692
|
|
|
4741
|
-
|
|
4693
|
+
qti-match-interaction.qti-match-tabular::part(control checked incorrect) {
|
|
4742
4694
|
border-color: var(--qti-incorrect);
|
|
4743
4695
|
background-color: var(--qti-incorrect);
|
|
4744
4696
|
}
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
.full-correct-response qti-match-interaction.qti-match-tabular {
|
|
4748
|
-
&::part(control checked) {
|
|
4697
|
+
:is(.full-correct-response qti-match-interaction.qti-match-tabular)::part(control checked) {
|
|
4749
4698
|
background-color: var(--qti-answer-bg);
|
|
4750
4699
|
color: var(--qti-answer-fg);
|
|
4751
4700
|
border-color: var(--qti-answer-border);
|
|
4752
4701
|
}
|
|
4753
4702
|
|
|
4754
|
-
|
|
4755
|
-
&::part(control-mark checkbox checked) {
|
|
4703
|
+
:is(.full-correct-response qti-match-interaction.qti-match-tabular)::part(control-mark radio checked),:is(.full-correct-response qti-match-interaction.qti-match-tabular)::part(control-mark checkbox checked) {
|
|
4756
4704
|
background-color: var(--qti-answer-fg);
|
|
4757
4705
|
}
|
|
4758
|
-
}
|
|
4759
4706
|
}
|
|
4707
|
+
|
|
4760
4708
|
/* This interaction's chip vocabulary — the bank chip, the placed chip, and the floating clone. One
|
|
4761
4709
|
such block per drag-drop interaction, opt-in; graphic-gap-match deliberately declares none. See
|
|
4762
4710
|
qti-states.css. Kept in the `global` layer, where these rules used to live, so cascade position is
|
|
@@ -4773,7 +4721,7 @@
|
|
|
4773
4721
|
sat on document.body it was in a different tree from the adopted stylesheet, and nothing — no
|
|
4774
4722
|
part, no attribute — could style it. */
|
|
4775
4723
|
@layer qti-components.global {
|
|
4776
|
-
qti-order-interaction :state(drag),
|
|
4724
|
+
qti-order-interaction :is(:state(drag), [data-state~='drag']),
|
|
4777
4725
|
[data-drag-clone][data-drag-interaction='qti-order-interaction'] {
|
|
4778
4726
|
/* Structural — the load-bearing box, never state-switched (layout-invariance contract).
|
|
4779
4727
|
box-sizing is deliberate: the clone is appended to document.body outside reset.css's
|
|
@@ -4824,7 +4772,7 @@
|
|
|
4824
4772
|
filter: var(--drag-filter, var(--qti-component-filter));
|
|
4825
4773
|
}
|
|
4826
4774
|
|
|
4827
|
-
qti-order-interaction :state(drag)::part(control)::before,
|
|
4775
|
+
qti-order-interaction :is(:state(drag), [data-state~='drag'])::part(control)::before,
|
|
4828
4776
|
qti-order-interaction::part(drag-control)::before,
|
|
4829
4777
|
qti-order-interaction ::part(drag-control)::before,
|
|
4830
4778
|
[data-drag-clone][data-drag-interaction='qti-order-interaction']::part(control)::before {
|
|
@@ -4839,19 +4787,15 @@
|
|
|
4839
4787
|
-webkit-mask: var(--qti-grip-mask) no-repeat center / contain;
|
|
4840
4788
|
}
|
|
4841
4789
|
}
|
|
4790
|
+
|
|
4842
4791
|
@layer qti-components.interactions.base {
|
|
4843
|
-
|
|
4844
|
-
&:state(dragzone-active)::part(drags) {
|
|
4792
|
+
qti-order-interaction:is(:state(dragzone-active), [data-state~='dragzone-active'])::part(drags) {
|
|
4845
4793
|
background-color: var(--qti-bg-active);
|
|
4846
4794
|
}
|
|
4847
|
-
|
|
4795
|
+
qti-order-interaction:is(:state(dragzone-enabled), [data-state~='dragzone-enabled'])::part(drags) {
|
|
4848
4796
|
background-color: var(--qti-bg-active);
|
|
4849
4797
|
}
|
|
4850
|
-
|
|
4851
|
-
& qti-simple-choice,
|
|
4852
|
-
/* Editor fake-drag projected into the interaction's drop-target shadow.
|
|
4853
|
-
Same `drag` styling so editor previews match runtime visuals. */
|
|
4854
|
-
&::part(drag) {
|
|
4798
|
+
qti-order-interaction::part(drag),qti-order-interaction qti-simple-choice,qti-order-interaction::part(drag) {
|
|
4855
4799
|
/* Structural — the load-bearing box, never state-switched (layout-invariance contract).
|
|
4856
4800
|
box-sizing is deliberate: the clone is appended to document.body outside reset.css's
|
|
4857
4801
|
@scope, so it inherits no border-box from anywhere else and this sets it. */
|
|
@@ -4899,30 +4843,30 @@
|
|
|
4899
4843
|
color: var(--drag-color, var(--qti-component-color));
|
|
4900
4844
|
opacity: var(--drag-opacity, var(--qti-component-opacity));
|
|
4901
4845
|
filter: var(--drag-filter, var(--qti-component-filter));
|
|
4902
|
-
|
|
4846
|
+
}
|
|
4847
|
+
[dragging]:is(qti-order-interaction::part(drag),qti-order-interaction qti-simple-choice,qti-order-interaction::part(drag)) {
|
|
4903
4848
|
pointer-events: none;
|
|
4904
4849
|
rotate: -2deg;
|
|
4905
4850
|
--drag-box-shadow: 0 8px 12px rgb(0 0 0 / 20%), 0 4px 8px rgb(0 0 0 / 10%);
|
|
4906
4851
|
}
|
|
4907
|
-
&:hover {
|
|
4908
4852
|
@media (hover: hover) {
|
|
4853
|
+
:is(qti-order-interaction::part(drag),qti-order-interaction qti-simple-choice,qti-order-interaction::part(drag)):hover {
|
|
4909
4854
|
background-color: color-mix(
|
|
4910
4855
|
in srgb,
|
|
4911
4856
|
var(--drag-background-color, var(--qti-component-background-color)) 92%,
|
|
4912
4857
|
black
|
|
4913
4858
|
);
|
|
4914
|
-
}
|
|
4915
4859
|
}
|
|
4916
|
-
|
|
4860
|
+
}
|
|
4861
|
+
:is(qti-order-interaction::part(drag),qti-order-interaction qti-simple-choice,qti-order-interaction::part(drag)):focus {
|
|
4917
4862
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
4918
4863
|
}
|
|
4919
|
-
}
|
|
4920
4864
|
/* Editor fake-drag projected into the interaction's drop-target shadow.
|
|
4921
4865
|
Same `drag` styling so editor previews match runtime visuals.
|
|
4922
4866
|
Kept as its own block (separate from the runtime-drag selector list
|
|
4923
4867
|
above) because a CSS comment between commas inside a nested selector
|
|
4924
4868
|
list is silently dropped by Chrome's nesting parser. */
|
|
4925
|
-
|
|
4869
|
+
qti-order-interaction::part(drag) {
|
|
4926
4870
|
/* Structural — the load-bearing box, never state-switched (layout-invariance contract).
|
|
4927
4871
|
box-sizing is deliberate: the clone is appended to document.body outside reset.css's
|
|
4928
4872
|
@scope, so it inherits no border-box from anywhere else and this sets it. */
|
|
@@ -4970,21 +4914,21 @@
|
|
|
4970
4914
|
color: var(--drag-color, var(--qti-component-color));
|
|
4971
4915
|
opacity: var(--drag-opacity, var(--qti-component-opacity));
|
|
4972
4916
|
filter: var(--drag-filter, var(--qti-component-filter));
|
|
4973
|
-
|
|
4917
|
+
}
|
|
4974
4918
|
@media (hover: hover) {
|
|
4919
|
+
:is(qti-order-interaction::part(drag)):hover {
|
|
4975
4920
|
background-color: color-mix(
|
|
4976
4921
|
in srgb,
|
|
4977
4922
|
var(--drag-background-color, var(--qti-component-background-color)) 92%,
|
|
4978
4923
|
black
|
|
4979
4924
|
);
|
|
4980
|
-
}
|
|
4981
4925
|
}
|
|
4982
|
-
|
|
4926
|
+
}
|
|
4927
|
+
:is(qti-order-interaction::part(drag)):focus {
|
|
4983
4928
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
4984
4929
|
}
|
|
4985
|
-
}
|
|
4986
4930
|
/* The drag's box — flex, centred, clipped — is in qti-order-interaction.styles.ts. */
|
|
4987
|
-
|
|
4931
|
+
qti-order-interaction::part(drag) {
|
|
4988
4932
|
/*
|
|
4989
4933
|
* No `width: 100%`. It stretched a placed chip to its slot, which is why order was the one
|
|
4990
4934
|
* entry in CHIP_BOX_KNOWN_BAD ("the placed chip stretches to fill its drop slot") — a 55px
|
|
@@ -5003,28 +4947,28 @@
|
|
|
5003
4947
|
* The drop's flags are part tokens rather than attributes: an attribute selector cannot follow
|
|
5004
4948
|
* `::part()`, and a <div> cannot carry a custom state (attachInternals throws). See setDropFlag.
|
|
5005
4949
|
*/
|
|
5006
|
-
|
|
4950
|
+
qti-order-interaction::part(active) {
|
|
5007
4951
|
background-color: var(--qti-bg-active);
|
|
5008
4952
|
}
|
|
5009
4953
|
|
|
5010
|
-
|
|
4954
|
+
qti-order-interaction::part(enabled) {
|
|
5011
4955
|
background-color: var(--qti-bg-active);
|
|
5012
4956
|
}
|
|
5013
4957
|
|
|
5014
4958
|
/* A filled drop hides its dashed outline and drop-here glyph. Hides — the border keeps its
|
|
5015
4959
|
width, or the column shifts 2px the instant a chip lands. */
|
|
5016
|
-
|
|
4960
|
+
qti-order-interaction::part(filled) {
|
|
5017
4961
|
--qti-drop-border: var(--qti-border-thickness, 1px) solid transparent;
|
|
5018
4962
|
--qti-drop-bg-img: none;
|
|
5019
4963
|
}
|
|
5020
4964
|
|
|
5021
|
-
|
|
4965
|
+
qti-order-interaction::part(drops) {
|
|
5022
4966
|
gap: var(--qti-gap);
|
|
5023
4967
|
}
|
|
5024
|
-
|
|
4968
|
+
qti-order-interaction::part(drags) {
|
|
5025
4969
|
gap: var(--qti-gap);
|
|
5026
4970
|
}
|
|
5027
|
-
|
|
4971
|
+
qti-order-interaction::part(drop) {
|
|
5028
4972
|
background-color: var(--drop-background-color, var(--qti-component-background-color));
|
|
5029
4973
|
background-image: var(--drop-background-image, var(--qti-component-background-image));
|
|
5030
4974
|
border-width: var(--drop-border-width, var(--qti-component-border-width));
|
|
@@ -5036,20 +4980,17 @@
|
|
|
5036
4980
|
opacity: var(--drop-opacity, var(--qti-component-opacity));
|
|
5037
4981
|
filter: var(--drop-filter, var(--qti-component-filter));
|
|
5038
4982
|
border-style: var(--drop-border-style, dashed);
|
|
5039
|
-
|
|
4983
|
+
}
|
|
4984
|
+
[enabled]:is(qti-order-interaction::part(drop)) {
|
|
5040
4985
|
background-color: var(--qti-bg-active);
|
|
5041
4986
|
}
|
|
5042
|
-
|
|
4987
|
+
:is(qti-order-interaction::part(drop)):focus {
|
|
5043
4988
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
5044
4989
|
}
|
|
5045
|
-
|
|
5046
|
-
&::part(active) {
|
|
4990
|
+
qti-order-interaction::part(active) {
|
|
5047
4991
|
background-color: var(--qti-bg-active);
|
|
5048
4992
|
}
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
qti-order-interaction {
|
|
5052
|
-
&::part(drops) {
|
|
4993
|
+
qti-order-interaction::part(drops) {
|
|
5053
4994
|
margin: 0;
|
|
5054
4995
|
border-radius: var(--qti-border-radius);
|
|
5055
4996
|
}
|
|
@@ -5059,18 +5000,18 @@
|
|
|
5059
5000
|
overhang the row by the border (42px row, 44px drop), which the drop's padding then doubled.
|
|
5060
5001
|
It also defeated `:has(qti-simple-choice) [part~='drop'] { align-self: flex-start }` in
|
|
5061
5002
|
qti-order-interaction.styles.ts. */
|
|
5062
|
-
|
|
5003
|
+
qti-order-interaction::part(drop) {
|
|
5063
5004
|
border: var(--qti-drop-border, var(--qti-border-thickness) dashed var(--qti-border-color));
|
|
5064
5005
|
border-radius: var(--qti-border-radius);
|
|
5065
5006
|
background-color: transparent;
|
|
5066
5007
|
background-image: var(--qti-drop-bg-img, revert-layer);
|
|
5067
5008
|
}
|
|
5068
5009
|
|
|
5069
|
-
|
|
5010
|
+
qti-order-interaction::part(active) {
|
|
5070
5011
|
background-color: var(--qti-bg-active);
|
|
5071
5012
|
}
|
|
5072
5013
|
|
|
5073
|
-
|
|
5014
|
+
qti-order-interaction::part(enabled) {
|
|
5074
5015
|
background-color: var(--qti-bg-active);
|
|
5075
5016
|
}
|
|
5076
5017
|
|
|
@@ -5081,7 +5022,7 @@
|
|
|
5081
5022
|
overlay (apps/e2e/src/stories/kennisnet/kennisnet.css), not here. In the base theme a placed
|
|
5082
5023
|
chip is just the neutral chip (@mixin drag), and its corrections route through --drag-*
|
|
5083
5024
|
like every other chip. */
|
|
5084
|
-
|
|
5025
|
+
qti-order-interaction qti-simple-choice {
|
|
5085
5026
|
/* Structural — the load-bearing box, never state-switched (layout-invariance contract).
|
|
5086
5027
|
box-sizing is deliberate: the clone is appended to document.body outside reset.css's
|
|
5087
5028
|
@scope, so it inherits no border-box from anywhere else and this sets it. */
|
|
@@ -5131,7 +5072,7 @@
|
|
|
5131
5072
|
filter: var(--drag-filter, var(--qti-component-filter));
|
|
5132
5073
|
}
|
|
5133
5074
|
|
|
5134
|
-
|
|
5075
|
+
qti-order-interaction::part(container) {
|
|
5135
5076
|
gap: 2rem;
|
|
5136
5077
|
}
|
|
5137
5078
|
|
|
@@ -5148,16 +5089,13 @@
|
|
|
5148
5089
|
* the bank above the drops" — that is what the qti-choices-top/bottom/left/right classes
|
|
5149
5090
|
* already do, and wiring orientation to them is a behaviour change, not a move.
|
|
5150
5091
|
*/
|
|
5151
|
-
|
|
5152
|
-
& qti-simple-choice,
|
|
5153
|
-
&::part(drag) {
|
|
5092
|
+
qti-order-interaction[orientation='vertical'] qti-simple-choice,qti-order-interaction[orientation='vertical']::part(drag) {
|
|
5154
5093
|
width: auto;
|
|
5155
5094
|
}
|
|
5156
|
-
}
|
|
5157
|
-
}
|
|
5158
5095
|
}
|
|
5096
|
+
|
|
5159
5097
|
@layer qti-components.interactions.states {
|
|
5160
|
-
qti-order-interaction qti-simple-choice:state(placeholder) {
|
|
5098
|
+
qti-order-interaction qti-simple-choice:is(:state(placeholder), [data-state~='placeholder']) {
|
|
5161
5099
|
/* The hole a spent/lifted chip leaves. Like the chip (see `drag`), it sets NO fill / border /
|
|
5162
5100
|
shadow of its own — those inherit from the resting chip (neutral by default, the brand's fill
|
|
5163
5101
|
when an overlay is on), so a brand can restyle the hole via a `:state(placeholder)` overlay
|
|
@@ -5168,7 +5106,7 @@
|
|
|
5168
5106
|
pointer-events: none;
|
|
5169
5107
|
}
|
|
5170
5108
|
|
|
5171
|
-
qti-order-interaction qti-simple-choice:state(dragging) {
|
|
5109
|
+
qti-order-interaction qti-simple-choice:is(:state(dragging), [data-state~='dragging']) {
|
|
5172
5110
|
/* The hole a spent/lifted chip leaves. Like the chip (see `drag`), it sets NO fill / border /
|
|
5173
5111
|
shadow of its own — those inherit from the resting chip (neutral by default, the brand's fill
|
|
5174
5112
|
when an overlay is on), so a brand can restyle the hole via a `:state(placeholder)` overlay
|
|
@@ -5182,7 +5120,7 @@
|
|
|
5182
5120
|
pointer-events: none;
|
|
5183
5121
|
}
|
|
5184
5122
|
|
|
5185
|
-
qti-order-interaction qti-simple-choice:state(return-anchor) {
|
|
5123
|
+
qti-order-interaction qti-simple-choice:is(:state(return-anchor), [data-state~='return-anchor']) {
|
|
5186
5124
|
border-color: var(--qti-drop-highlight-border-color);
|
|
5187
5125
|
box-shadow: inset 0 0 0 var(--qti-drop-highlight-border-width, 2px)
|
|
5188
5126
|
color-mix(in srgb, var(--qti-drop-highlight-border-color) 55%, transparent);
|
|
@@ -5197,6 +5135,7 @@
|
|
|
5197
5135
|
background-color: var(--qti-drop-highlight-enabled-bg);
|
|
5198
5136
|
}
|
|
5199
5137
|
}
|
|
5138
|
+
|
|
5200
5139
|
@layer qti-components.interactions.corrections {
|
|
5201
5140
|
/*
|
|
5202
5141
|
* Judgement paint, via the shared mixin — every other drag-drop interaction already uses it.
|
|
@@ -5220,16 +5159,16 @@
|
|
|
5220
5159
|
`[data-drag-clone]:state(candidate-*)` went with it and is deliberately NOT reproduced — a clone
|
|
5221
5160
|
carries no custom states at all, because cloneNode does not copy ElementInternals (measured), so
|
|
5222
5161
|
that selector never matched anything. */
|
|
5223
|
-
qti-order-interaction :state(drag):state(candidate-correct),
|
|
5224
|
-
qti-order-interaction::part(drag):state(candidate-correct) {
|
|
5162
|
+
qti-order-interaction :is(:state(drag), [data-state~='drag']):is(:state(candidate-correct), [data-state~='candidate-correct']),
|
|
5163
|
+
qti-order-interaction::part(drag):is(:state(candidate-correct), [data-state~='candidate-correct']) {
|
|
5225
5164
|
--drag-background-color: var(--qti-correct-light);
|
|
5226
5165
|
--drag-color: var(--qti-correct);
|
|
5227
5166
|
--drag-border-color: var(--qti-correct);
|
|
5228
5167
|
--drag-box-shadow: none;
|
|
5229
5168
|
}
|
|
5230
5169
|
|
|
5231
|
-
qti-order-interaction :state(drag):state(candidate-incorrect),
|
|
5232
|
-
qti-order-interaction::part(drag):state(candidate-incorrect) {
|
|
5170
|
+
qti-order-interaction :is(:state(drag), [data-state~='drag']):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']),
|
|
5171
|
+
qti-order-interaction::part(drag):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']) {
|
|
5233
5172
|
--drag-background-color: var(--qti-incorrect-light);
|
|
5234
5173
|
--drag-color: var(--qti-incorrect);
|
|
5235
5174
|
--drag-border-color: var(--qti-incorrect);
|
|
@@ -5239,6 +5178,7 @@
|
|
|
5239
5178
|
/* The bank is hidden by the interaction itself, on :host([answer-key]) — see
|
|
5240
5179
|
qti-order-interaction.styles.ts. */
|
|
5241
5180
|
}
|
|
5181
|
+
|
|
5242
5182
|
/* This interaction's chip vocabulary — the bank chip, the placed chip, and the floating clone. One
|
|
5243
5183
|
such block per drag-drop interaction, opt-in; graphic-gap-match deliberately declares none. See
|
|
5244
5184
|
qti-states.css. Kept in the `global` layer, where these rules used to live, so cascade position is
|
|
@@ -5260,7 +5200,7 @@
|
|
|
5260
5200
|
and text colour from the removed rule and nothing else. Deleting that rule without this block
|
|
5261
5201
|
turned the associate bank chips transparent, square and un-grabbable — measured, not guessed. */
|
|
5262
5202
|
@layer qti-components.global {
|
|
5263
|
-
qti-associate-interaction :state(drag),
|
|
5203
|
+
qti-associate-interaction :is(:state(drag), [data-state~='drag']),
|
|
5264
5204
|
[data-drag-clone][data-drag-interaction='qti-associate-interaction'] {
|
|
5265
5205
|
/* Structural — the load-bearing box, never state-switched (layout-invariance contract).
|
|
5266
5206
|
box-sizing is deliberate: the clone is appended to document.body outside reset.css's
|
|
@@ -5311,7 +5251,7 @@
|
|
|
5311
5251
|
filter: var(--drag-filter, var(--qti-component-filter));
|
|
5312
5252
|
}
|
|
5313
5253
|
|
|
5314
|
-
qti-associate-interaction :state(drag)::part(control)::before,
|
|
5254
|
+
qti-associate-interaction :is(:state(drag), [data-state~='drag'])::part(control)::before,
|
|
5315
5255
|
qti-associate-interaction::part(drag-control)::before,
|
|
5316
5256
|
qti-associate-interaction ::part(drag-control)::before,
|
|
5317
5257
|
[data-drag-clone][data-drag-interaction='qti-associate-interaction']::part(control)::before {
|
|
@@ -5326,8 +5266,8 @@
|
|
|
5326
5266
|
-webkit-mask: var(--qti-grip-mask) no-repeat center / contain;
|
|
5327
5267
|
}
|
|
5328
5268
|
}
|
|
5269
|
+
|
|
5329
5270
|
@layer qti-components.interactions.base {
|
|
5330
|
-
qti-associate-interaction {
|
|
5331
5271
|
/*
|
|
5332
5272
|
* NO `--drag-border-color: transparent` here, and that absence is the rule.
|
|
5333
5273
|
*
|
|
@@ -5343,20 +5283,17 @@
|
|
|
5343
5283
|
* Associate was the only interaction doing this; match, order and gap-match all let the bank
|
|
5344
5284
|
* chip take --qti-component-border-color, and now so does this one.
|
|
5345
5285
|
*/
|
|
5346
|
-
|
|
5286
|
+
qti-associate-interaction qti-simple-associable-choice {
|
|
5347
5287
|
padding: var(--qti-drag-padding);
|
|
5348
5288
|
}
|
|
5349
5289
|
|
|
5350
|
-
|
|
5290
|
+
qti-associate-interaction:is(:state(dragzone-active), [data-state~='dragzone-active']) slot[name='qti-simple-associable-choice'] {
|
|
5351
5291
|
background-color: var(--qti-bg-active);
|
|
5352
5292
|
}
|
|
5353
|
-
|
|
5293
|
+
qti-associate-interaction:is(:state(dragzone-enabled), [data-state~='dragzone-enabled']) slot[name='qti-simple-associable-choice'] {
|
|
5354
5294
|
background-color: var(--qti-bg-active);
|
|
5355
5295
|
}
|
|
5356
|
-
|
|
5357
|
-
/* A placed chip lives in a shadow root; `::part(drag)` is the only way in. This used to be
|
|
5358
|
-
`::part(qti-simple-associable-choice)`, a part named after the tag. */
|
|
5359
|
-
&::part(drag) {
|
|
5296
|
+
qti-associate-interaction qti-simple-associable-choice::part(drag),qti-associate-interaction::part(drag) {
|
|
5360
5297
|
/* Structural — the load-bearing box, never state-switched (layout-invariance contract).
|
|
5361
5298
|
box-sizing is deliberate: the clone is appended to document.body outside reset.css's
|
|
5362
5299
|
@scope, so it inherits no border-box from anywhere else and this sets it. */
|
|
@@ -5404,29 +5341,29 @@
|
|
|
5404
5341
|
color: var(--drag-color, var(--qti-component-color));
|
|
5405
5342
|
opacity: var(--drag-opacity, var(--qti-component-opacity));
|
|
5406
5343
|
filter: var(--drag-filter, var(--qti-component-filter));
|
|
5407
|
-
|
|
5344
|
+
}
|
|
5408
5345
|
@media (hover: hover) {
|
|
5346
|
+
:is(qti-associate-interaction qti-simple-associable-choice::part(drag),qti-associate-interaction::part(drag)):hover {
|
|
5409
5347
|
background-color: color-mix(
|
|
5410
5348
|
in srgb,
|
|
5411
5349
|
var(--drag-background-color, var(--qti-component-background-color)) 92%,
|
|
5412
5350
|
black
|
|
5413
5351
|
);
|
|
5414
|
-
}
|
|
5415
5352
|
}
|
|
5416
|
-
|
|
5353
|
+
}
|
|
5354
|
+
:is(qti-associate-interaction qti-simple-associable-choice::part(drag),qti-associate-interaction::part(drag)):focus {
|
|
5417
5355
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
5418
5356
|
}
|
|
5419
|
-
|
|
5357
|
+
[dragging]:is(qti-associate-interaction qti-simple-associable-choice::part(drag),qti-associate-interaction::part(drag)) {
|
|
5420
5358
|
pointer-events: none;
|
|
5421
5359
|
rotate: -2deg;
|
|
5422
5360
|
--drag-box-shadow: 0 8px 12px rgb(0 0 0 / 20%), 0 4px 8px rgb(0 0 0 / 10%);
|
|
5423
5361
|
}
|
|
5424
|
-
}
|
|
5425
5362
|
/* Editor fake-drag projected into the interaction's drop-target shadow.
|
|
5426
5363
|
Kept as a separate block (not merged into the comma list above)
|
|
5427
5364
|
because a CSS comment between commas in a nested selector list is
|
|
5428
5365
|
silently dropped by Chrome's nesting parser. */
|
|
5429
|
-
|
|
5366
|
+
qti-associate-interaction::part(drag) {
|
|
5430
5367
|
/* Structural — the load-bearing box, never state-switched (layout-invariance contract).
|
|
5431
5368
|
box-sizing is deliberate: the clone is appended to document.body outside reset.css's
|
|
5432
5369
|
@scope, so it inherits no border-box from anywhere else and this sets it. */
|
|
@@ -5474,29 +5411,29 @@
|
|
|
5474
5411
|
color: var(--drag-color, var(--qti-component-color));
|
|
5475
5412
|
opacity: var(--drag-opacity, var(--qti-component-opacity));
|
|
5476
5413
|
filter: var(--drag-filter, var(--qti-component-filter));
|
|
5477
|
-
|
|
5414
|
+
}
|
|
5478
5415
|
@media (hover: hover) {
|
|
5416
|
+
:is(qti-associate-interaction::part(drag)):hover {
|
|
5479
5417
|
background-color: color-mix(
|
|
5480
5418
|
in srgb,
|
|
5481
5419
|
var(--drag-background-color, var(--qti-component-background-color)) 92%,
|
|
5482
5420
|
black
|
|
5483
5421
|
);
|
|
5484
|
-
}
|
|
5485
5422
|
}
|
|
5486
|
-
|
|
5423
|
+
}
|
|
5424
|
+
:is(qti-associate-interaction::part(drag)):focus {
|
|
5487
5425
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
5488
5426
|
}
|
|
5489
|
-
}
|
|
5490
5427
|
/* `display: grid` lives in qti-associate-interaction.styles.ts, which already declares it on
|
|
5491
5428
|
[part~='drop'] alongside the drop's min-height/min-width. */
|
|
5492
5429
|
/* A filled drop hides its dashed edge — see the note in qti-gap-match-interaction.css. Every
|
|
5493
5430
|
associate drop holds exactly one chip (the div never carries match-max), so no capacity guard
|
|
5494
5431
|
is needed here. Colour only: the width stays, or the row shifts when a chip lands. */
|
|
5495
|
-
|
|
5432
|
+
qti-associate-interaction::part(filled) {
|
|
5496
5433
|
--drop-border-color: transparent;
|
|
5497
5434
|
}
|
|
5498
5435
|
|
|
5499
|
-
|
|
5436
|
+
qti-associate-interaction::part(drop) {
|
|
5500
5437
|
background-color: var(--drop-background-color, var(--qti-component-background-color));
|
|
5501
5438
|
background-image: var(--drop-background-image, var(--qti-component-background-image));
|
|
5502
5439
|
border-width: var(--drop-border-width, var(--qti-component-border-width));
|
|
@@ -5509,7 +5446,7 @@
|
|
|
5509
5446
|
filter: var(--drop-filter, var(--qti-component-filter));
|
|
5510
5447
|
border-style: var(--drop-border-style, dashed);
|
|
5511
5448
|
}
|
|
5512
|
-
|
|
5449
|
+
qti-associate-interaction::part(drop):focus {
|
|
5513
5450
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
5514
5451
|
}
|
|
5515
5452
|
|
|
@@ -5524,15 +5461,15 @@
|
|
|
5524
5461
|
* Deleted here: `&::part(drop)[dragging] { @mixin act }`. An attribute selector after ::part()
|
|
5525
5462
|
* never matches; that rule has never applied.
|
|
5526
5463
|
*/
|
|
5527
|
-
|
|
5464
|
+
qti-associate-interaction::part(active) {
|
|
5528
5465
|
background-color: var(--qti-bg-active);
|
|
5529
5466
|
}
|
|
5530
5467
|
|
|
5531
|
-
|
|
5468
|
+
qti-associate-interaction::part(enabled) {
|
|
5532
5469
|
background-color: var(--qti-bg-active);
|
|
5533
5470
|
}
|
|
5534
|
-
}
|
|
5535
5471
|
}
|
|
5472
|
+
|
|
5536
5473
|
@layer qti-components.interactions.states {
|
|
5537
5474
|
qti-simple-associable-choice::part(drag),
|
|
5538
5475
|
qti-associate-interaction::part(drag) {
|
|
@@ -5594,7 +5531,7 @@
|
|
|
5594
5531
|
background-color: var(--qti-drop-highlight-enabled-bg);
|
|
5595
5532
|
}
|
|
5596
5533
|
|
|
5597
|
-
qti-associate-interaction qti-simple-associable-choice:state(placeholder) {
|
|
5534
|
+
qti-associate-interaction qti-simple-associable-choice:is(:state(placeholder), [data-state~='placeholder']) {
|
|
5598
5535
|
/* The hole a spent/lifted chip leaves. Like the chip (see `drag`), it sets NO fill / border /
|
|
5599
5536
|
shadow of its own — those inherit from the resting chip (neutral by default, the brand's fill
|
|
5600
5537
|
when an overlay is on), so a brand can restyle the hole via a `:state(placeholder)` overlay
|
|
@@ -5606,7 +5543,7 @@
|
|
|
5606
5543
|
pointer-events: none;
|
|
5607
5544
|
}
|
|
5608
5545
|
|
|
5609
|
-
qti-associate-interaction qti-simple-associable-choice:state(dragging) {
|
|
5546
|
+
qti-associate-interaction qti-simple-associable-choice:is(:state(dragging), [data-state~='dragging']) {
|
|
5610
5547
|
/* The hole a spent/lifted chip leaves. Like the chip (see `drag`), it sets NO fill / border /
|
|
5611
5548
|
shadow of its own — those inherit from the resting chip (neutral by default, the brand's fill
|
|
5612
5549
|
when an overlay is on), so a brand can restyle the hole via a `:state(placeholder)` overlay
|
|
@@ -5620,22 +5557,23 @@
|
|
|
5620
5557
|
pointer-events: none;
|
|
5621
5558
|
}
|
|
5622
5559
|
|
|
5623
|
-
qti-associate-interaction qti-simple-associable-choice:state(placeholder) > *,
|
|
5624
|
-
qti-associate-interaction qti-simple-associable-choice:state(dragging) > * {
|
|
5560
|
+
qti-associate-interaction qti-simple-associable-choice:is(:state(placeholder), [data-state~='placeholder']) > *,
|
|
5561
|
+
qti-associate-interaction qti-simple-associable-choice:is(:state(dragging), [data-state~='dragging']) > * {
|
|
5625
5562
|
visibility: hidden;
|
|
5626
5563
|
}
|
|
5627
5564
|
|
|
5628
|
-
qti-associate-interaction qti-simple-associable-choice:state(placeholder)::part(label),
|
|
5629
|
-
qti-associate-interaction qti-simple-associable-choice:state(dragging)::part(label) {
|
|
5565
|
+
qti-associate-interaction qti-simple-associable-choice:is(:state(placeholder), [data-state~='placeholder'])::part(label),
|
|
5566
|
+
qti-associate-interaction qti-simple-associable-choice:is(:state(dragging), [data-state~='dragging'])::part(label) {
|
|
5630
5567
|
visibility: hidden;
|
|
5631
5568
|
}
|
|
5632
5569
|
|
|
5633
|
-
qti-associate-interaction qti-simple-associable-choice:state(return-anchor) {
|
|
5570
|
+
qti-associate-interaction qti-simple-associable-choice:is(:state(return-anchor), [data-state~='return-anchor']) {
|
|
5634
5571
|
border-color: var(--qti-drop-highlight-border-color);
|
|
5635
5572
|
box-shadow: inset 0 0 0 var(--qti-drop-highlight-border-width, 2px)
|
|
5636
5573
|
color-mix(in srgb, var(--qti-drop-highlight-border-color) 55%, transparent);
|
|
5637
5574
|
}
|
|
5638
5575
|
}
|
|
5576
|
+
|
|
5639
5577
|
@layer qti-components.interactions.corrections {
|
|
5640
5578
|
/* A corrected chip — in the bank, and where it landed. Moved here from the shared
|
|
5641
5579
|
qti-corrections.css, which claimed `:state(drag)` for EVERY interaction in one unscoped rule:
|
|
@@ -5643,18 +5581,18 @@
|
|
|
5643
5581
|
`[data-drag-clone]:state(candidate-*)` went with it and is deliberately NOT reproduced — a clone
|
|
5644
5582
|
carries no custom states at all, because cloneNode does not copy ElementInternals (measured), so
|
|
5645
5583
|
that selector never matched anything. */
|
|
5646
|
-
qti-associate-interaction :state(drag):state(candidate-correct),
|
|
5647
|
-
qti-simple-associable-choice::part(drag):state(candidate-correct),
|
|
5648
|
-
qti-associate-interaction::part(drag):state(candidate-correct) {
|
|
5584
|
+
qti-associate-interaction :is(:state(drag), [data-state~='drag']):is(:state(candidate-correct), [data-state~='candidate-correct']),
|
|
5585
|
+
qti-simple-associable-choice::part(drag):is(:state(candidate-correct), [data-state~='candidate-correct']),
|
|
5586
|
+
qti-associate-interaction::part(drag):is(:state(candidate-correct), [data-state~='candidate-correct']) {
|
|
5649
5587
|
--drag-background-color: var(--qti-correct-light);
|
|
5650
5588
|
--drag-color: var(--qti-correct);
|
|
5651
5589
|
--drag-border-color: var(--qti-correct);
|
|
5652
5590
|
--drag-box-shadow: none;
|
|
5653
5591
|
}
|
|
5654
5592
|
|
|
5655
|
-
qti-associate-interaction :state(drag):state(candidate-incorrect),
|
|
5656
|
-
qti-simple-associable-choice::part(drag):state(candidate-incorrect),
|
|
5657
|
-
qti-associate-interaction::part(drag):state(candidate-incorrect) {
|
|
5593
|
+
qti-associate-interaction :is(:state(drag), [data-state~='drag']):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']),
|
|
5594
|
+
qti-simple-associable-choice::part(drag):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']),
|
|
5595
|
+
qti-associate-interaction::part(drag):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']) {
|
|
5658
5596
|
--drag-background-color: var(--qti-incorrect-light);
|
|
5659
5597
|
--drag-color: var(--qti-incorrect);
|
|
5660
5598
|
--drag-border-color: var(--qti-incorrect);
|
|
@@ -5664,6 +5602,7 @@
|
|
|
5664
5602
|
/* The bank is hidden by the interaction itself, on :host([answer-key]) — see
|
|
5665
5603
|
qti-associate-interaction.styles.ts. */
|
|
5666
5604
|
}
|
|
5605
|
+
|
|
5667
5606
|
@layer qti-components.interactions.base {
|
|
5668
5607
|
qti-graphic-order-interaction {
|
|
5669
5608
|
--qti-graphic-order-pin-size: calc(var(--qti-select-point-marker-size, 1.5rem) * 1.2);
|
|
@@ -5671,8 +5610,9 @@
|
|
|
5671
5610
|
--qti-graphic-order-pin-fill: var(--qti-background, #fff);
|
|
5672
5611
|
--qti-graphic-order-pin-number-size: calc(var(--qti-graphic-order-pin-size) * 0.5);
|
|
5673
5612
|
--qti-graphic-order-pin-svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 384 512'%3E%3Cpath d='M192 500C145 434 106 386 77 344C49 305 32 272 32 224C32 135.6 103.6 64 192 64s160 71.6 160 160c0 48-17 81-45 120c-29 42-68 90-115 156z' fill='white' stroke='currentColor' stroke-width='28' stroke-linejoin='round'/%3E%3C/svg%3E");
|
|
5613
|
+
}
|
|
5674
5614
|
|
|
5675
|
-
|
|
5615
|
+
qti-graphic-order-interaction qti-hotspot-choice {
|
|
5676
5616
|
width: 100%;
|
|
5677
5617
|
height: 100%;
|
|
5678
5618
|
background-color: color-mix(in srgb, var(--qti-border-color) 18%, transparent);
|
|
@@ -5681,63 +5621,58 @@
|
|
|
5681
5621
|
transition:
|
|
5682
5622
|
background-color var(--qti-motion-duration-fast, 0.15s) ease,
|
|
5683
5623
|
border-color var(--qti-motion-duration-fast, 0.15s) ease;
|
|
5624
|
+
}
|
|
5684
5625
|
|
|
5685
|
-
|
|
5626
|
+
[shape='circle']:is(qti-graphic-order-interaction qti-hotspot-choice) {
|
|
5686
5627
|
min-width: calc(var(--qti-graphic-order-pin-size) * 0.6);
|
|
5687
5628
|
min-height: calc(var(--qti-graphic-order-pin-size) * 0.6);
|
|
5688
5629
|
}
|
|
5689
5630
|
|
|
5690
|
-
|
|
5631
|
+
[shape='poly']:is(qti-graphic-order-interaction qti-hotspot-choice) {
|
|
5691
5632
|
background-color: color-mix(in srgb, var(--qti-border-color) 18%, transparent);
|
|
5692
5633
|
box-shadow: none;
|
|
5693
5634
|
}
|
|
5694
5635
|
|
|
5695
|
-
|
|
5696
|
-
&[shape='rect']:hover,
|
|
5697
|
-
&[shape='ellipse']:hover {
|
|
5636
|
+
[shape='circle']:is(qti-graphic-order-interaction qti-hotspot-choice):hover,[shape='rect']:is(qti-graphic-order-interaction qti-hotspot-choice):hover,[shape='ellipse']:is(qti-graphic-order-interaction qti-hotspot-choice):hover {
|
|
5698
5637
|
background-color: color-mix(in srgb, var(--qti-border-active) 12%, transparent);
|
|
5699
5638
|
}
|
|
5700
5639
|
|
|
5701
|
-
|
|
5640
|
+
[shape='poly']:is(qti-graphic-order-interaction qti-hotspot-choice):hover {
|
|
5702
5641
|
background-color: color-mix(in srgb, var(--qti-border-active) 20%, transparent);
|
|
5703
5642
|
box-shadow: none;
|
|
5704
5643
|
}
|
|
5705
5644
|
|
|
5706
|
-
|
|
5707
|
-
&[shape='rect']:focus-visible,
|
|
5708
|
-
&[shape='ellipse']:focus-visible {
|
|
5645
|
+
[shape='circle']:is(qti-graphic-order-interaction qti-hotspot-choice):focus-visible,[shape='rect']:is(qti-graphic-order-interaction qti-hotspot-choice):focus-visible,[shape='ellipse']:is(qti-graphic-order-interaction qti-hotspot-choice):focus-visible {
|
|
5709
5646
|
outline: var(--qti-focus-border-width) solid var(--qti-focus-color);
|
|
5710
5647
|
outline-offset: 2px;
|
|
5711
5648
|
}
|
|
5712
5649
|
|
|
5713
|
-
|
|
5650
|
+
[shape='poly']:is(qti-graphic-order-interaction qti-hotspot-choice):focus-visible {
|
|
5714
5651
|
outline: var(--qti-focus-border-width) solid var(--qti-focus-color);
|
|
5715
5652
|
outline-offset: 2px;
|
|
5716
5653
|
}
|
|
5717
5654
|
|
|
5718
|
-
|
|
5655
|
+
[aria-ordervalue]:is(qti-graphic-order-interaction qti-hotspot-choice) {
|
|
5719
5656
|
border: 0 !important;
|
|
5720
5657
|
box-shadow: none;
|
|
5721
5658
|
background-color: color-mix(in srgb, var(--qti-selected-bg) 35%, transparent);
|
|
5722
5659
|
}
|
|
5723
5660
|
|
|
5724
|
-
|
|
5725
|
-
&[aria-ordervalue]:focus-visible {
|
|
5661
|
+
[aria-ordervalue]:is(qti-graphic-order-interaction qti-hotspot-choice):hover,[aria-ordervalue]:is(qti-graphic-order-interaction qti-hotspot-choice):focus-visible {
|
|
5726
5662
|
border-color: transparent !important;
|
|
5727
5663
|
}
|
|
5728
|
-
|
|
5664
|
+
[aria-ordercorrectvalue][aria-ordervalue]:is(qti-graphic-order-interaction qti-hotspot-choice):not([shape='circle'])::after {
|
|
5729
5665
|
content: 'C=' attr(aria-ordercorrectvalue) ' R=' attr(aria-ordervalue) !important;
|
|
5730
5666
|
color: var(--qti-correct);
|
|
5731
5667
|
}
|
|
5732
|
-
|
|
5668
|
+
[aria-ordercorrectvalue]:is(qti-graphic-order-interaction qti-hotspot-choice):not([aria-ordervalue]):not([shape='circle'])::after {
|
|
5733
5669
|
content: 'C=' attr(aria-ordercorrectvalue) !important;
|
|
5734
5670
|
color: var(--qti-correct);
|
|
5735
5671
|
}
|
|
5736
|
-
}
|
|
5737
5672
|
|
|
5738
5673
|
/* The pin's face. Where it sits — absolute, anchored to its hotspot, above the image — is
|
|
5739
5674
|
placement, and lives in qti-graphic-order-interaction.styles.ts as ::slotted(). */
|
|
5740
|
-
|
|
5675
|
+
qti-graphic-order-interaction .cito-graphic-order-marker {
|
|
5741
5676
|
width: var(--qti-graphic-order-pin-size);
|
|
5742
5677
|
height: var(--qti-graphic-order-pin-size);
|
|
5743
5678
|
padding-top: calc(var(--qti-graphic-order-pin-size) * 0.2);
|
|
@@ -5750,47 +5685,41 @@
|
|
|
5750
5685
|
pointer-events: none;
|
|
5751
5686
|
}
|
|
5752
5687
|
|
|
5753
|
-
|
|
5688
|
+
qti-graphic-order-interaction .cito-graphic-order-marker--poly {
|
|
5754
5689
|
width: calc(var(--qti-select-point-marker-size, 1.5rem) * 0.72);
|
|
5755
5690
|
height: calc(var(--qti-select-point-marker-size, 1.5rem) * 0.72);
|
|
5756
5691
|
font-size: calc(var(--qti-select-point-marker-size, 1.5rem) * 0.45);
|
|
5757
5692
|
padding-top: calc(var(--qti-select-point-marker-size, 1.5rem) * 0.14);
|
|
5758
5693
|
}
|
|
5759
|
-
}
|
|
5760
5694
|
}
|
|
5695
|
+
|
|
5761
5696
|
@layer qti-components.interactions.states {
|
|
5762
|
-
|
|
5763
|
-
& qti-hotspot-choice {
|
|
5764
|
-
&:state(readonly) {
|
|
5697
|
+
:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(readonly), [data-state~='readonly']) {
|
|
5765
5698
|
cursor: pointer;
|
|
5766
5699
|
}
|
|
5767
5700
|
|
|
5768
|
-
|
|
5701
|
+
:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(disabled), [data-state~='disabled']) {
|
|
5769
5702
|
cursor: not-allowed;
|
|
5770
5703
|
}
|
|
5771
5704
|
|
|
5772
|
-
|
|
5773
|
-
&[shape='rect']:state(checked),
|
|
5774
|
-
&[shape='ellipse']:state(checked) {
|
|
5705
|
+
[shape='circle']:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(checked), [data-state~='checked']),[shape='rect']:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(checked), [data-state~='checked']),[shape='ellipse']:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(checked), [data-state~='checked']) {
|
|
5775
5706
|
background-color: color-mix(in srgb, var(--qti-selected-bg) 35%, transparent);
|
|
5776
5707
|
}
|
|
5777
5708
|
|
|
5778
|
-
|
|
5709
|
+
[shape='poly']:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(checked), [data-state~='checked']) {
|
|
5779
5710
|
background-color: color-mix(in srgb, var(--qti-selected-bg) 40%, transparent);
|
|
5780
5711
|
box-shadow: none;
|
|
5781
5712
|
}
|
|
5782
5713
|
|
|
5783
|
-
|
|
5784
|
-
&[aria-ordervalue] {
|
|
5714
|
+
[aria-ordervalue]:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(checked), [data-state~='checked']),[aria-ordervalue]:is(qti-graphic-order-interaction qti-hotspot-choice) {
|
|
5785
5715
|
border-color: transparent !important;
|
|
5786
5716
|
}
|
|
5787
|
-
}
|
|
5788
5717
|
|
|
5789
5718
|
/* No qti-selections-light / -dark here. Appendix B.1 of the QTI 3 implementation guide defines
|
|
5790
5719
|
that class pair for qti-hotspot-interaction and qti-graphic-gap-match-interaction only, and no
|
|
5791
5720
|
item in this repo ever set it on a graphic-order interaction. What was here overrode the neutral
|
|
5792
5721
|
drag-bank highlight below with --qti-light-* and --qti-dark-* colours that nothing could reach. */
|
|
5793
|
-
|
|
5722
|
+
qti-graphic-order-interaction:is(:state(dragzone-active), [data-state~='dragzone-active'])::part(drags) {
|
|
5794
5723
|
/* Direct properties, not slots: ::part(drags) is a bare slot container with no paint role of
|
|
5795
5724
|
its own (the other interactions paint it with `@mixin dropping`, also direct), so there is
|
|
5796
5725
|
no --<role>-* to switch. Inlined from `@mixin act`. */
|
|
@@ -5798,85 +5727,70 @@
|
|
|
5798
5727
|
background-color: var(--qti-bg-active);
|
|
5799
5728
|
}
|
|
5800
5729
|
|
|
5801
|
-
|
|
5730
|
+
qti-graphic-order-interaction:is(:state(dragzone-enabled), [data-state~='dragzone-enabled'])::part(drags) {
|
|
5802
5731
|
background-color: var(--qti-bg-active);
|
|
5803
5732
|
}
|
|
5804
|
-
}
|
|
5805
5733
|
}
|
|
5734
|
+
|
|
5806
5735
|
@layer qti-components.interactions.corrections {
|
|
5807
|
-
|
|
5808
|
-
& qti-hotspot-choice {
|
|
5809
|
-
&[shape='circle']:state(correct-response),
|
|
5810
|
-
&[shape='rect']:state(correct-response),
|
|
5811
|
-
&[shape='ellipse']:state(correct-response) {
|
|
5736
|
+
[shape='circle']:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(correct-response), [data-state~='correct-response']),[shape='rect']:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(correct-response), [data-state~='correct-response']),[shape='ellipse']:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(correct-response), [data-state~='correct-response']) {
|
|
5812
5737
|
background-color: color-mix(in srgb, var(--qti-answer-bg) 75%, transparent);
|
|
5813
5738
|
}
|
|
5814
5739
|
|
|
5815
|
-
|
|
5740
|
+
[shape='poly']:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(correct-response), [data-state~='correct-response']) {
|
|
5816
5741
|
background-color: color-mix(in srgb, var(--qti-answer-bg) 80%, transparent);
|
|
5817
5742
|
box-shadow: none;
|
|
5818
5743
|
}
|
|
5819
5744
|
|
|
5820
|
-
|
|
5821
|
-
&[shape='rect']:state(candidate-correct),
|
|
5822
|
-
&[shape='ellipse']:state(candidate-correct) {
|
|
5745
|
+
[shape='circle']:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(candidate-correct), [data-state~='candidate-correct']),[shape='rect']:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(candidate-correct), [data-state~='candidate-correct']),[shape='ellipse']:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(candidate-correct), [data-state~='candidate-correct']) {
|
|
5823
5746
|
background-color: color-mix(in srgb, var(--qti-correct) 35%, transparent);
|
|
5824
5747
|
}
|
|
5825
5748
|
|
|
5826
|
-
|
|
5749
|
+
[shape='poly']:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(candidate-correct), [data-state~='candidate-correct']) {
|
|
5827
5750
|
background-color: color-mix(in srgb, var(--qti-correct) 40%, transparent);
|
|
5828
5751
|
box-shadow: none;
|
|
5829
5752
|
}
|
|
5830
5753
|
|
|
5831
|
-
|
|
5832
|
-
&[shape='rect']:state(candidate-incorrect),
|
|
5833
|
-
&[shape='ellipse']:state(candidate-incorrect) {
|
|
5754
|
+
[shape='circle']:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']),[shape='rect']:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']),[shape='ellipse']:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']) {
|
|
5834
5755
|
background-color: color-mix(in srgb, var(--qti-incorrect) 35%, transparent);
|
|
5835
5756
|
}
|
|
5836
5757
|
|
|
5837
|
-
|
|
5758
|
+
[shape='poly']:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']) {
|
|
5838
5759
|
background-color: color-mix(in srgb, var(--qti-incorrect) 40%, transparent);
|
|
5839
5760
|
box-shadow: none;
|
|
5840
5761
|
}
|
|
5841
5762
|
|
|
5842
|
-
|
|
5843
|
-
&[aria-ordervalue]:state(candidate-correct),
|
|
5844
|
-
&[aria-ordervalue]:state(candidate-incorrect) {
|
|
5763
|
+
[aria-ordervalue]:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(correct-response), [data-state~='correct-response']),[aria-ordervalue]:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(candidate-correct), [data-state~='candidate-correct']),[aria-ordervalue]:is(qti-graphic-order-interaction qti-hotspot-choice):is(:state(candidate-incorrect), [data-state~='candidate-incorrect']) {
|
|
5845
5764
|
border-color: transparent !important;
|
|
5846
5765
|
}
|
|
5847
|
-
}
|
|
5848
|
-
}
|
|
5849
5766
|
}
|
|
5767
|
+
|
|
5850
5768
|
@layer qti-components.interactions.base {
|
|
5851
|
-
qti-graphic-associate-interaction {
|
|
5852
5769
|
/*
|
|
5853
5770
|
* qti-associable-hotspot does not use ActiveElementMixin, so it carries no
|
|
5854
5771
|
* checked/disabled/readonly custom states. Selection and correction are drawn as
|
|
5855
5772
|
* ::part(line) / ::part(point) instead. Give it a `part="drag"` and the
|
|
5856
5773
|
* ActiveElementMixin states before adding state-dependent rules here.
|
|
5857
5774
|
*/
|
|
5858
|
-
& qti-associable-hotspot {
|
|
5859
5775
|
/* `[shape='square']` used to be in this selector. It is not a QTI shape — the spec has
|
|
5860
5776
|
circle, default, ellipse, poly and rect — positionShapes has no branch for it, and no item
|
|
5861
5777
|
in the repo sets it. */
|
|
5862
|
-
|
|
5778
|
+
[shape='circle']:is(qti-graphic-associate-interaction qti-associable-hotspot) {
|
|
5863
5779
|
background-color: transparent;
|
|
5864
|
-
|
|
5780
|
+
}
|
|
5781
|
+
[shape='circle']:is(qti-graphic-associate-interaction qti-associable-hotspot):focus {
|
|
5865
5782
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
5866
5783
|
}
|
|
5867
|
-
}
|
|
5868
|
-
}
|
|
5869
|
-
}
|
|
5870
5784
|
}
|
|
5785
|
+
|
|
5871
5786
|
@layer qti-components.interactions.states {
|
|
5872
|
-
qti-graphic-associate-interaction {
|
|
5873
5787
|
|
|
5874
5788
|
|
|
5875
5789
|
/* No qti-selections-light / -dark here. Appendix B.1 of the QTI 3 implementation guide defines
|
|
5876
5790
|
that class pair for qti-hotspot-interaction and qti-graphic-gap-match-interaction only, and no
|
|
5877
5791
|
item in this repo ever set it on a graphic-associate interaction. What was here overrode the neutral
|
|
5878
5792
|
drag-bank highlight below with --qti-light-* and --qti-dark-* colours that nothing could reach. */
|
|
5879
|
-
|
|
5793
|
+
qti-graphic-associate-interaction:is(:state(dragzone-active), [data-state~='dragzone-active'])::part(drags) {
|
|
5880
5794
|
/* Direct properties, not slots: ::part(drags) is a bare slot container with no paint role of
|
|
5881
5795
|
its own (the other interactions paint it with `@mixin dropping`, also direct), so there is
|
|
5882
5796
|
no --<role>-* to switch. Inlined from `@mixin act`. */
|
|
@@ -5884,17 +5798,18 @@
|
|
|
5884
5798
|
background-color: var(--qti-bg-active);
|
|
5885
5799
|
}
|
|
5886
5800
|
|
|
5887
|
-
|
|
5801
|
+
qti-graphic-associate-interaction:is(:state(dragzone-enabled), [data-state~='dragzone-enabled'])::part(drags) {
|
|
5888
5802
|
background-color: var(--qti-bg-active);
|
|
5889
5803
|
}
|
|
5890
|
-
}
|
|
5891
5804
|
}
|
|
5805
|
+
|
|
5892
5806
|
@layer qti-components.interactions.base{
|
|
5893
5807
|
qti-slider-interaction {
|
|
5894
5808
|
--qti-tick-color: rgb(229 231 235 / 100%);
|
|
5895
5809
|
--qti-tick-width: 1px;
|
|
5896
5810
|
}
|
|
5897
5811
|
}
|
|
5812
|
+
|
|
5898
5813
|
@layer qti-components.interactions.base {
|
|
5899
5814
|
qti-select-point-interaction {
|
|
5900
5815
|
/*
|
|
@@ -5911,37 +5826,34 @@ qti-slider-interaction {
|
|
|
5911
5826
|
* itself (`[part~='correct']`), which is deeper than this host declaration.
|
|
5912
5827
|
*/
|
|
5913
5828
|
--qti-select-point-marker-color: var(--qti-primary);
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
&:focus {
|
|
5829
|
+
}
|
|
5830
|
+
:is(qti-select-point-interaction::part(point)):focus {
|
|
5917
5831
|
box-shadow: 0 0 0 var(--qti-focus-border-width) var(--qti-focus-color);
|
|
5918
5832
|
}
|
|
5919
|
-
}
|
|
5920
|
-
}
|
|
5921
5833
|
}
|
|
5834
|
+
|
|
5922
5835
|
@layer qti-components.interactions.corrections {
|
|
5923
|
-
qti-select-point-interaction {
|
|
5924
5836
|
/* Same knob as the resting colour above — these set `color` before, which stopped reaching the
|
|
5925
5837
|
marker once it was no longer painted with `currentColor`. */
|
|
5926
|
-
|
|
5838
|
+
qti-select-point-interaction::part(correct) {
|
|
5927
5839
|
--qti-select-point-marker-color: var(--qti-correct);
|
|
5928
5840
|
}
|
|
5929
5841
|
|
|
5930
|
-
|
|
5842
|
+
qti-select-point-interaction::part(incorrect) {
|
|
5931
5843
|
--qti-select-point-marker-color: var(--qti-incorrect);
|
|
5932
5844
|
}
|
|
5933
|
-
}
|
|
5934
5845
|
}
|
|
5846
|
+
|
|
5935
5847
|
@layer qti-components.interactions.base{
|
|
5936
|
-
qti-position-object-stage {
|
|
5937
|
-
& qti-position-object-interaction {
|
|
5848
|
+
qti-position-object-stage qti-position-object-interaction {
|
|
5938
5849
|
/* no styles necessary, only layout styles, defined in the component */
|
|
5939
5850
|
}
|
|
5940
5851
|
}
|
|
5941
|
-
|
|
5852
|
+
|
|
5942
5853
|
@layer qti-components.interactions.base{
|
|
5943
5854
|
/* `display: block` lives in qti-prompt.styles.ts, which already declares it on :host. */
|
|
5944
5855
|
}
|
|
5856
|
+
|
|
5945
5857
|
@layer qti-components.interactions.corrections{
|
|
5946
5858
|
/*
|
|
5947
5859
|
* What is LEFT here is what the base class owns.
|
|
@@ -5998,14 +5910,14 @@ qti-position-object-stage {
|
|
|
5998
5910
|
/* A cloned interaction presents the answer key rather than a candidate judgement. What is left
|
|
5999
5911
|
here is the part no interaction owns: any chip, anywhere. The text-entry and inline-choice
|
|
6000
5912
|
halves moved into their own files — those name one interaction each, so they belong to it. */
|
|
6001
|
-
.full-correct-response :state(drag),
|
|
5913
|
+
.full-correct-response :is(:state(drag), [data-state~='drag']),
|
|
6002
5914
|
.full-correct-response ::part(drag) {
|
|
6003
5915
|
background-color: var(--qti-answer-bg);
|
|
6004
5916
|
color: var(--qti-answer-fg);
|
|
6005
5917
|
border-color: var(--qti-answer-border);
|
|
6006
5918
|
}
|
|
6007
5919
|
|
|
6008
|
-
.full-correct-response :state(drag)::part(control)::before,
|
|
5920
|
+
.full-correct-response :is(:state(drag), [data-state~='drag'])::part(control)::before,
|
|
6009
5921
|
.full-correct-response ::part(drag-control)::before {
|
|
6010
5922
|
content: '';
|
|
6011
5923
|
background-color: var(--qti-answer-fg);
|
|
@@ -6013,6 +5925,7 @@ qti-position-object-stage {
|
|
|
6013
5925
|
-webkit-mask: var(--qti-check-mask) no-repeat center / contain;
|
|
6014
5926
|
}
|
|
6015
5927
|
}
|
|
5928
|
+
|
|
6016
5929
|
@layer qti-components.elements{
|
|
6017
5930
|
/* `display: block` is declared by the element itself, in qti-rubric-block.ts. */
|
|
6018
5931
|
qti-rubric-block {
|
|
@@ -6023,14 +5936,17 @@ qti-rubric-block {
|
|
|
6023
5936
|
margin-top: var(--qti-gap);
|
|
6024
5937
|
}
|
|
6025
5938
|
}
|
|
5939
|
+
|
|
6026
5940
|
@layer qti-components.elements{
|
|
6027
5941
|
qti-feedback-inline::part(feedback) {
|
|
6028
5942
|
}
|
|
6029
5943
|
}
|
|
5944
|
+
|
|
6030
5945
|
@layer qti-components.elements{
|
|
6031
5946
|
qti-feedback-block::part(feedback) {
|
|
6032
5947
|
}
|
|
6033
5948
|
}
|
|
5949
|
+
|
|
6034
5950
|
@layer qti-components.elements{
|
|
6035
5951
|
/*
|
|
6036
5952
|
* Neither selector below matches anything this repo renders — `qti-modal-feedback-custom` is not a
|
|
@@ -6049,6 +5965,7 @@ qti-feedback-block::part(feedback) {
|
|
|
6049
5965
|
margin-top: var(--qti-gap);
|
|
6050
5966
|
}
|
|
6051
5967
|
}
|
|
5968
|
+
|
|
6052
5969
|
@layer qti-components.global{
|
|
6053
5970
|
/*
|
|
6054
5971
|
* Cross-interaction custom states.
|
|
@@ -6098,13 +6015,15 @@ qti-feedback-block::part(feedback) {
|
|
|
6098
6015
|
* paint. If the double indication ever reads as too much, the fix is here or in the mixin, not
|
|
6099
6016
|
* a display value.
|
|
6100
6017
|
*/
|
|
6101
|
-
:state(show-correct-response) {
|
|
6018
|
+
:is(:state(show-correct-response), [data-state~='show-correct-response']) {
|
|
6102
6019
|
outline: var(--qti-border-thickness) dashed var(--qti-correct);
|
|
6103
6020
|
outline-offset: 0.25rem;
|
|
6104
6021
|
}
|
|
6105
6022
|
}
|
|
6023
|
+
|
|
6106
6024
|
/* Item-shell structure (what is shown, what is hidden). Kept out of styles/qti-theme/ because it is
|
|
6107
6025
|
structure rather than paint — that directory is where the no-layout-in-theme lint rule applies. */
|
|
6026
|
+
|
|
6108
6027
|
@layer qti-components.global{
|
|
6109
6028
|
|
|
6110
6029
|
/**
|