Grid is two divs with classes on them. It announces nothing, takes no tab stop and names nothing, so this tab is about the page around it: the order a reader meets the Cols in, what the alignment means, and whether the layout works at a 320px viewport.
Row and Col add no semantics
Both components render a plain <div> with classes on it. There is no role, no ARIA attribute, no label and no keyboard handling anywhere in the grid, and the kit adds none.
Nothing here is announced. A grid is invisible to a screen reader, which is the correct outcome for a layout primitive.
Any ARIA attribute or role you pass lands on the div, but a Col is rarely the right element to carry a role.
The accessible structure of the page comes from what you put inside the Cols: headings in order, a <nav> or <main> landmark where the region deserves one, a list where the content is a list.
Visual order against DOM order
push, pull and order only move what you see.push and pull move a Col with position: relative, and order moves it with flexbox ordering. The DOM order stays the same, and the DOM order is what a keyboard, a screen reader and a reading-order tool follow.
A keyboard or screen reader user meets the Cols in source order, while a sighted reader meets them in the order on screen. After a swap or two, tabbing seems to jump around the screen.
Fine where the visual order is a presentation detail and both orders are sensible, the classic case being a sidebar that should sit above the main column on a phone and beside it on a desktop.
Wrong where the reading order differs, for example when the swap puts a summary before the thing it summarizes. Change the markup instead, or render the two orders as two branches.
offset is different. It adds real space before the Col and changes no order.
Test this by tabbing, not by looking. A layout built with order, push or pull looks identical whether the DOM agrees with it or not, so the only way the mismatch shows up is to put the keyboard through it at each breakpoint you support.
A grid is layout, not a table
The 24 columns are a way to measure width, not a data structure. A Row of Cols carries no row or cell semantics, which is right for a layout grid.
Do not add role="table", role="row" or role="cell" to make a grid read as tabular. A role promises a full set of relationships (headers, row and column positions, navigation) that a layout grid cannot keep, so it makes the reading worse rather than better.
ARIA's role="grid" is a keyboard navigable widget, not this.
When the content is tabular, use Table (or a real <table>) inside a Col, and let the grid do nothing but place it.
Cols that happen to line up under each other are not a column of related values to anyone who is not looking at the screen. If the alignment carries meaning, say it in the content.
Reflow and small viewports
WCAG 2.1 Reflow (1.4.10, AA) asks that content still work at a viewport 320px wide without two dimensional scrolling. A responsive grid is the usual way a page meets that, and a careless one is the usual way it fails.
A Col's xs is the smallest step and applies at every width, so whatever it says has to work down to 320px. For anything holding prose, that means xs={24}.
A Col with no responsive props keeps its desktop span on a phone. A span={6} of a 320px viewport is 80px wide, and 80px of running text is a column of single words.
wrap={false} turns off the wrapping reflow depends on. Where you need it, pair it with an overflow-x-auto on a wrapper so the content is still reachable.
Reflow is tested by zoom as much as by width: 400% zoom on a 1280px window is the same 320px of layout, so the same fix serves the low vision case and the phone case at once.
Use a smaller gutter on small screens, like gutter={{ xs: 8, sm: 16, md: 24 }}. At 320px a 24px gutter takes width the content needs.
Nothing here manages focus
The grid takes no tab stop, moves no focus and traps nothing. Cols are not focusable, so a keyboard reader passes straight through to whatever you rendered inside them.
A layout that changes at a breakpoint does not move focus with it. If a resize or an orientation change re-renders the region, the focused element has to survive that re-render or focus falls back to the body.
Do not put tabIndex on a Col to make a region reachable. A focusable div with no role and no name announces nothing. Give the content a heading and let a reader navigate by headings.
A useBreakpoint branch that swaps a Modal for a Drawer swaps one focus trap for another, in the middle of a session, on a resize. Try it with the keyboard.
Skip links belong to the landmarks inside the grid, not to the Cols. Point them at the <main> you rendered, which has an id and a name.