Appearance
Tine Preset Support Pack
Diagnostic and troubleshooting reference for the Tine hardware preset — comparison table, specs-table mode, bulk pricing, and hardware metafields.
FAQ
Q: The comparison table columns are not sorting correctly.
A: The comparison table sort uses natural alphanumeric ordering. Hardware-specific values:
- Metric thread (M8, M10, M12) sort correctly as strings (M10 > M8 alphabetically, but the natural sort treats them as M10, M12, M8 by number — verify with the diagnostic snippet)
- For correct metric-thread sort, prefix with zero-padding: M08, M10, M12 instead of M8
- Composite codes like
A2-70sort as strings; this is correct for standards-code columns
Q: The specs table mode is showing unsorted data in the wrong column.
A: In orientation: rows mode, the table renders spec name/value pairs from section blocks in the order they were added in the theme editor. The table is intentionally non-sortable in rows mode (sorting attribute names is not meaningful). To reorder rows, reorder the blocks in the theme editor.
Q: The bulk-pricing pill is showing but no discount is applied.
A: This is by design — the pill is a messaging display aid only. It does not apply a Shopify discount automatically. To apply actual discounts:
- Set up a quantity-break discount in Shopify (Discounts → Create discount → Amount off products → Minimum purchase quantity) or use a price-breaks app.
- Set the
bulk_thresholdin the Quick Order section to match your first discount tier quantity. - The pill will show the savings percentage informationally; the actual discount is applied at checkout by Shopify's discount engine.
Q: Quick order section renders no products.
A: The Quick Order section requires a collection to be selected. This was F-TINE-QUICKORD-01 in the audit. Check:
- In the theme editor, navigate to Quick Order → Section settings. Is a collection selected?
- Does the selected collection have at least one published product?
- If the collection is empty, the section shows a guided empty state — check your collection rules or populate products.
Q: Cross-reference block shows "Part number unavailable".
A: The cross-reference block reads from the product description or manually entered block settings. Check the cross_reference_mpn and cross_reference_manufacturer fields are filled in the block settings in the theme editor.
Decision Tree: "Why is my comparison table not rendering?"
Symptom: Comparison table section appears but has no columns
-> Are there blocks added to the comparison table section?
-> In theme editor: Sections → Comparison table → check for column blocks
-> No blocks: add at least 2 comparison-column blocks
-> Yes: Continue
-> Is orientation set correctly?
-> 'columns' mode: expects multiple column blocks
-> 'rows' mode: expects spec-row blocks
-> Wrong block type for current orientation: switch to the matching block type
-> Are column headings empty?
-> Empty column heading will render but look invisible — check each block has a heading
-> Is the niche_metafield_namespace required for this section?
-> Comparison table does not read metafields directly — specs-table-row PDP blocks do
-> If metafield data not showing on PDP: check metafield definitions in Shopify AdminValidator Interpretation
"Lighthouse: Comparison table — interactive element does not have an accessible name"
The comparison table sort buttons are <button> elements wrapping <th> text. If Lighthouse flags this, the button may lack an aria-label. Check that each sortable column header's <button> has either visible text content or an aria-label that names the sort action. The theme ships aria-label="Sort by {column}" — verify this is present in the rendered HTML.
"axe: aria-sort value is not allowed"
The comparison table uses aria-sort="ascending" and aria-sort="descending" per ARIA spec. Valid values are none, ascending, descending, other. If axe flags this, a custom edit may have introduced an invalid value. Check niche-tine.js for the ariaSortUpdate() function.
"Theme check: quick-order section missing collection setting"
This is expected in a fresh install before the merchant selects a collection. Set the collection in the theme editor before deploying. If you see this in CI, configure a default collection in the section schema default: value for the collection picker setting.
Console Diagnostic Snippet
js
(function tineDiagnostic() {
'use strict';
const compTable = document.querySelector('.comparison-table');
const r = {
preset: document.querySelector('meta[name="uisce-preset"]')?.content ?? 'unknown',
comparisonTable: {
present: !!compTable,
orientation: compTable?.dataset?.orientation ?? 'not found',
columnCount: document.querySelectorAll('.comparison-table__column').length,
rowCount: document.querySelectorAll('.comparison-table__row').length,
sortButtonsPresent: document.querySelectorAll('[aria-sort]').length,
lastAriaSortValue:
document.querySelector('[aria-sort]:not([aria-sort="none"])')?.getAttribute('aria-sort') ?? 'none',
},
quickOrder: {
present: !!document.querySelector('.quick-order'),
productCount: document.querySelectorAll('.quick-order__item').length,
bulkPillVisible: !!document.querySelector('.quick-order__bulk-pill:not([hidden])'),
},
nicheTineLoaded: !!document.querySelector('script[src*="niche-tine"]'),
presetCSS: !!document.querySelector('link[href*="preset-tine"]'),
nicheNamespace: document.querySelector('[data-niche-namespace]')?.dataset?.nicheNamespace ?? 'not found',
};
console.group('%cTine Diagnostic Report', 'color:#c0392b;font-weight:bold;font-size:14px');
console.table(r.comparisonTable);
console.log('Quick order:', r.quickOrder);
console.log('niche-tine.js loaded:', r.nicheTineLoaded);
console.log('Preset CSS:', r.presetCSS);
console.groupEnd();
return r;
})();Accessibility Diagnostic
Comparison table sort accessibility check
js
(function checkComparisonTableA11y() {
const table = document.querySelector('.comparison-table table');
if (!table) {
console.warn('No comparison table found');
return;
}
const sortButtons = table.querySelectorAll('th [aria-sort]');
const liveRegion = document.querySelector('[role="status"]');
console.log({
tablePresent: true,
sortableColumns: sortButtons.length,
ariaSortValues: [...sortButtons].map((b) => b.getAttribute('aria-sort')),
liveRegionPresent: !!liveRegion,
caption: table.querySelector('caption')?.textContent?.trim() ?? 'MISSING',
});
})();Expected: sortableColumns > 0 (if sort enabled), valid aria-sort values.
Quick order bulk pill check
js
const pills = document.querySelectorAll('.quick-order__bulk-pill');
const liveRegion = document.querySelector('[aria-live="polite"]');
console.log({
pillCount: pills.length,
visiblePills: [...pills].filter((p) => !p.hidden).length,
liveRegionPresent: !!liveRegion,
pillText: pills[0]?.textContent?.trim() ?? 'none visible',
});Localization Notes
Comparison table locale keys
Sort direction announcements use sections.comparison_table.sort_ascending / sections.comparison_table.sort_descending locale keys. All 50 locales covered. The bulk-pricing pill label uses sections.quick_order.bulk_save_label — check this key is translated correctly for your non-EN markets.
Standards names are not localized
Technical standards names (ASTM F3125, ISO 898-1, DIN EN ISO 7045) are English-language designations recognized internationally. They should NOT be translated — use the official designation string as the spec value.
Curl Cheat-Sheet
bash
# Verify Product + additionalProperty JSON-LD on a hardware product
curl -s "https://your-store.myshopify.com/products/m8-hex-bolt" \
| grep -A 15 '"additionalProperty"'
# Check niche_metafield_namespace on comparison table page
curl -s "https://your-store.myshopify.com/pages/compare" \
| grep 'data-niche-namespace'
# Verify preset-tine.css is linked
curl -s "https://your-store.myshopify.com" \
| grep 'preset-tine'
# Check aria-sort attribute is present on comparison table
curl -s "https://your-store.myshopify.com/pages/compare" \
| grep 'aria-sort'Localization Notes
Comparison table locale keys
Sort direction announcements use sections.comparison_table.sort_ascending and sections.comparison_table.sort_descending locale keys. Both are present in all 50 locales. The specs-table-row PDP block section strings are in blocks.specs_table_row.*.
Bulk-pricing pill locale key
The savings percentage shown in the bulk-pricing pill uses sections.quick_order.bulk_save_label with {percent} interpolation. Check this key is correctly translated for your EU/international markets (Irish/British English, German, French etc.).
Standards references are language-neutral
Technical standards designations (ASTM F3125, ISO 898-1, DIN EN ISO 7045, BS EN ISO) are not localized. Use them verbatim in spec values. If you need to explain a standard in a customer-facing description, add a richtext block in your product description.
Deployment Checklist
Before going live with the Tine preset:
- [ ]
settings.presetset totinein Theme settings - [ ] Comparison table has at least 2 column or 2 row blocks populated
- [ ]
orientationsetting is set to the correct mode for each table usage context - [ ] Quick order section has a collection selected
- [ ]
bulk_thresholdandbulk_save_percentmatch your actual pricing tier - [ ] Product metafield definitions for
uisce_tine.*created in Shopify Admin - [ ] At least 4 products have
materialanddimensions_mmmetafields populated - [ ] Header menu includes product navigation (Compare, Products, Bulk Order)
- [ ] JSON-LD validated: Product + additionalProperty appears on product pages
- [ ] Comparison table aria-sort is verified: run diagnostic snippet above
- [ ]
preset-tine.csslinked: confirmed via curl check above
Support pack last updated: 2026-05-03 (Phase 06.10 closeout)